OBS User unknown 2009-04-02 15:28:15 +00:00 committed by Git OBS Bridge
parent f331331acb
commit 9987222f7b
27 changed files with 2459 additions and 22669 deletions

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:82a4195effbfd56af6eb3dd80de9690c1fef3fa8b9c25457037d3d591d15dcd9
size 468691

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1f85b4ed494c73b43fcfb195758ee6570615fd6e5f7cf09fd27644a1838019ae
size 980339

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3c6e610cae207e7af87ab471228ab3311536a27f061d86dd0c75413ae8f96d09
size 498156

3
Linux-PAM-1.0.91.tar.bz2 Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b729820717cbf07a7ab07672180d070ce384ac923cc2129904fdc975342a35c4
size 1112332

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2333
cvs.diff Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +0,0 @@
--- libpam/pam_dispatch.c 3 Dec 2008 14:16:33 -0000 1.13
+++ libpam/pam_dispatch.c 4 Feb 2009 13:48:02 -0000
@@ -132,11 +132,10 @@
}
/*
- * use_cached_chain is how we ensure that the setcred/close_session
- * and chauthtok(2) modules are called in the same order as they did
- * when they were invoked as auth/open_session/chauthtok(1). This
- * feature was added in 0.75 to make the behavior of pam_setcred
- * sane. It was debugged by release 0.76.
+ * use_cached_chain is how we ensure that the setcred and
+ * close_session modules are called in the same order as they did
+ * when they were invoked as auth/open_session. This feature was
+ * added in 0.75 to make the behavior of pam_setcred sane.
*/
if (use_cached_chain != _PAM_PLEASE_FREEZE) {
@@ -358,9 +357,6 @@
break;
case PAM_CHAUTHTOK:
h = pamh->handlers.conf.chauthtok;
- if (flags & PAM_UPDATE_AUTHTOK) {
- use_cached_chain = _PAM_MUST_BE_FROZEN;
- }
break;
default:
pam_syslog(pamh, LOG_ERR, "undefined fn choice; %d", choice);
--- libpam/pam_password.c 24 Jul 2006 15:47:40 -0000 1.5
+++ libpam/pam_password.c 4 Feb 2009 13:48:02 -0000
@@ -24,6 +24,13 @@
return PAM_SYSTEM_ERR;
}
+ /* applications are not allowed to set this flags */
+ if (flags & (PAM_PRELIM_CHECK | PAM_UPDATE_AUTHTOK)) {
+ syslog(LOG_ERR, _PAM_SYSTEM_LOG_PREFIX
+ "PAM_PRELIM_CHECK or PAM_UPDATE_AUTHTOK set by application");
+ return PAM_SYSTEM_ERR;
+ }
+
if (pamh->former.choice == PAM_NOT_STACKED) {
_pam_start_timer(pamh); /* we try to make the time for a failure
independent of the time it takes to
@@ -58,4 +67,3 @@
return retval;
}
-

View File

@ -1,561 +0,0 @@
Index: modules/pam_selinux/pam_selinux.8.xml
===================================================================
RCS file: /cvsroot/pam/Linux-PAM/modules/pam_selinux/pam_selinux.8.xml,v
retrieving revision 1.2
diff -u -p -r1.2 pam_selinux.8.xml
--- modules/pam_selinux/pam_selinux.8.xml 15 Jun 2007 10:17:22 -0000 1.2
+++ modules/pam_selinux/pam_selinux.8.xml 19 May 2008 15:44:08 -0000
@@ -37,6 +37,9 @@
select_context
</arg>
<arg choice="opt">
+ env_params
+ </arg>
+ <arg choice="opt">
use_current_range
</arg>
</cmdsynopsis>
@@ -137,12 +140,30 @@
</varlistentry>
<varlistentry>
<term>
+ <option>env_params</option>
+ </term>
+ <listitem>
+ <para>
+ Attempt to obtain a custom security context role from PAM environment.
+ If MLS is on obtain also sensitivity level. This option and the
+ select_context option are mutually exclusive. The respective PAM
+ environment variables are <emphasis>SELINUX_ROLE_REQUESTED</emphasis>,
+ <emphasis>SELINUX_LEVEL_REQUESTED</emphasis>, and
+ <emphasis>SELINUX_USE_CURRENT_RANGE</emphasis>. The first two variables
+ are self describing and the last one if set to 1 makes the PAM module behave as
+ if the use_current_range was specified on the command line of the module.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
<option>use_current_range</option>
</term>
<listitem>
<para>
- Use the sensitivity range of the process for the user context.
- This option and the select_context option are mutually exclusive.
+ Use the sensitivity level of the current process for the user context
+ instead of the default level. Also supresses asking of the
+ sensitivity level from the user or obtaining it from PAM environment.
</para>
</listitem>
</varlistentry>
Index: modules/pam_selinux/pam_selinux.c
===================================================================
RCS file: /cvsroot/pam/Linux-PAM/modules/pam_selinux/pam_selinux.c,v
retrieving revision 1.16
diff -u -p -r1.16 pam_selinux.c
--- modules/pam_selinux/pam_selinux.c 22 Apr 2008 19:21:37 -0000 1.16
+++ modules/pam_selinux/pam_selinux.c 19 May 2008 15:44:08 -0000
@@ -2,8 +2,9 @@
* A module for Linux-PAM that will set the default security context after login
* via PAM.
*
- * Copyright (c) 2003 Red Hat, Inc.
+ * Copyright (c) 2003-2008 Red Hat, Inc.
* Written by Dan Walsh <dwalsh@redhat.com>
+ * Additional improvements by Tomas Mraz <tmraz@redhat.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -138,15 +139,22 @@ send_text (pam_handle_t *pamh, const cha
*/
static int
query_response (pam_handle_t *pamh, const char *text, const char *def,
- char **responses, int debug)
+ char **response, int debug)
{
int rc;
if (def)
- rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, responses, "%s [%s] ", text, def);
+ rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, response, "%s [%s] ", text, def);
else
- rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, responses, "%s ", text);
- if (debug)
- pam_syslog(pamh, LOG_NOTICE, "%s %s", text, responses[0]);
+ rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, response, "%s ", text);
+
+ if (*response == NULL) {
+ rc = PAM_CONV_ERR;
+ }
+
+ if (rc != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_WARNING, "No response to query: %s", text);
+ } else if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "%s %s", text, *response);
return rc;
}
@@ -157,13 +165,15 @@ manual_context (pam_handle_t *pamh, cons
context_t new_context;
int mls_enabled = is_selinux_mls_enabled();
char *type=NULL;
- char *responses=NULL;
+ char *response=NULL;
while (1) {
- query_response(pamh,
- _("Would you like to enter a security context? [N] "), NULL,
- &responses,debug);
- if ((responses[0] == 'y') || (responses[0] == 'Y'))
+ if (query_response(pamh,
+ _("Would you like to enter a security context? [N] "), NULL,
+ &response, debug) != PAM_SUCCESS)
+ return NULL;
+
+ if ((response[0] == 'y') || (response[0] == 'Y'))
{
if (mls_enabled)
new_context = context_new ("user:role:type:level");
@@ -176,26 +186,29 @@ manual_context (pam_handle_t *pamh, cons
if (context_user_set (new_context, user))
goto fail_set;
- _pam_drop(responses);
+ _pam_drop(response);
/* Allow the user to enter each field of the context individually */
- query_response(pamh,_("role:"), NULL, &responses,debug);
- if (responses[0] != '\0') {
- if (context_role_set (new_context, responses))
+ if (query_response(pamh, _("role:"), NULL, &response, debug) == PAM_SUCCESS &&
+ response[0] != '\0') {
+ if (context_role_set (new_context, response))
goto fail_set;
- if (get_default_type(responses, &type))
+ if (get_default_type(response, &type))
goto fail_set;
if (context_type_set (new_context, type))
goto fail_set;
}
- _pam_drop(responses);
+ _pam_drop(response);
+
if (mls_enabled)
{
- query_response(pamh,_("level:"), NULL, &responses,debug);
- if (responses[0] != '\0') {
- if (context_range_set (new_context, responses))
+ if (query_response(pamh, _("level:"), NULL, &response, debug) == PAM_SUCCESS &&
+ response[0] != '\0') {
+ if (context_range_set (new_context, response))
goto fail_set;
}
+ _pam_drop(response);
}
+
/* Get the string value of the context and see if it is valid. */
if (!security_check_context(context_str(new_context))) {
newcon = strdup(context_str(new_context));
@@ -204,16 +217,17 @@ manual_context (pam_handle_t *pamh, cons
}
else
send_text(pamh,_("Not a valid security context"),debug);
- context_free (new_context);
+
+ context_free (new_context);
}
else {
- _pam_drop(responses);
+ _pam_drop(response);
return NULL;
}
} /* end while */
fail_set:
free(type);
- _pam_drop(responses);
+ _pam_drop(response);
context_free (new_context);
return NULL;
}
@@ -239,69 +253,91 @@ static int mls_range_allowed(pam_handle_
}
static security_context_t
-config_context (pam_handle_t *pamh, security_context_t puser_context, int debug)
+config_context (pam_handle_t *pamh, security_context_t defaultcon, int use_current_range, int debug)
{
security_context_t newcon=NULL;
context_t new_context;
int mls_enabled = is_selinux_mls_enabled();
- char *responses=NULL;
+ char *response=NULL;
char *type=NULL;
char resp_val = 0;
- pam_prompt (pamh, PAM_TEXT_INFO, NULL, _("Default Security Context %s\n"), puser_context);
+ pam_prompt (pamh, PAM_TEXT_INFO, NULL, _("Default Security Context %s\n"), defaultcon);
while (1) {
- query_response(pamh,
+ if (query_response(pamh,
_("Would you like to enter a different role or level?"), "n",
- &responses,debug);
-
- resp_val = responses[0];
- _pam_drop(responses);
+ &response, debug) == PAM_SUCCESS) {
+ resp_val = response[0];
+ _pam_drop(response);
+ } else {
+ resp_val = 'N';
+ }
if ((resp_val == 'y') || (resp_val == 'Y'))
{
- new_context = context_new(puser_context);
-
+ if ((new_context = context_new(defaultcon)) == NULL)
+ goto fail_set;
+
/* Allow the user to enter role and level individually */
- query_response(pamh,_("role:"), context_role_get(new_context),
- &responses, debug);
- if (responses[0]) {
- if (get_default_type(responses, &type)) {
- pam_prompt (pamh, PAM_ERROR_MSG, NULL, _("No default type for role %s\n"), responses);
- _pam_drop(responses);
+ if (query_response(pamh, _("role:"), context_role_get(new_context),
+ &response, debug) == PAM_SUCCESS && response[0]) {
+ if (get_default_type(response, &type)) {
+ pam_prompt (pamh, PAM_ERROR_MSG, NULL, _("No default type for role %s\n"), response);
+ _pam_drop(response);
continue;
} else {
- if (context_role_set(new_context, responses))
+ if (context_role_set(new_context, response))
goto fail_set;
if (context_type_set (new_context, type))
goto fail_set;
}
}
- _pam_drop(responses);
+ _pam_drop(response);
+
if (mls_enabled)
{
- query_response(pamh,_("level:"), context_range_get(new_context),
- &responses, debug);
- if (responses[0]) {
- if (context_range_set(new_context, responses))
- goto fail_set;
+ if (use_current_range) {
+ security_context_t mycon = NULL;
+ context_t my_context;
+
+ if (getcon(&mycon) != 0)
+ goto fail_set;
+ my_context = context_new(mycon);
+ if (my_context == NULL) {
+ freecon(mycon);
+ goto fail_set;
+ }
+ freecon(mycon);
+ if (context_range_set(new_context, context_range_get(my_context))) {
+ context_free(my_context);
+ goto fail_set;
+ }
+ context_free(my_context);
+ } else if (query_response(pamh, _("level:"), context_range_get(new_context),
+ &response, debug) == PAM_SUCCESS && response[0]) {
+ if (context_range_set(new_context, response))
+ goto fail_set;
}
- _pam_drop(responses);
+ _pam_drop(response);
}
+
if (debug)
pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", context_str(new_context));
/* Get the string value of the context and see if it is valid. */
if (!security_check_context(context_str(new_context))) {
newcon = strdup(context_str(new_context));
- context_free (new_context);
+ if (newcon == NULL)
+ goto fail_set;
+ context_free(new_context);
/* we have to check that this user is allowed to go into the
range they have specified ... role is tied to an seuser, so that'll
be checked at setexeccon time */
- if (mls_enabled && !mls_range_allowed(pamh, puser_context, newcon, debug)) {
- pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", puser_context, newcon);
+ if (mls_enabled && !mls_range_allowed(pamh, defaultcon, newcon, debug)) {
+ pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
- send_audit_message(pamh, 0, puser_context, newcon);
+ send_audit_message(pamh, 0, defaultcon, newcon);
free(newcon);
goto fail_range;
@@ -309,26 +345,120 @@ config_context (pam_handle_t *pamh, secu
return newcon;
}
else {
- send_audit_message(pamh, 0, puser_context, context_str(new_context));
+ send_audit_message(pamh, 0, defaultcon, context_str(new_context));
send_text(pamh,_("Not a valid security context"),debug);
}
context_free(new_context); /* next time around allocates another */
}
else
- return strdup(puser_context);
+ return strdup(defaultcon);
} /* end while */
return NULL;
fail_set:
free(type);
- _pam_drop(responses);
+ _pam_drop(response);
context_free (new_context);
- send_audit_message(pamh, 0, puser_context, NULL);
+ send_audit_message(pamh, 0, defaultcon, NULL);
fail_range:
return NULL;
}
+static security_context_t
+context_from_env (pam_handle_t *pamh, security_context_t defaultcon, int env_params, int use_current_range, int debug)
+{
+ security_context_t newcon = NULL;
+ context_t new_context;
+ context_t my_context = NULL;
+ int mls_enabled = is_selinux_mls_enabled();
+ const char *env = NULL;
+ char *type = NULL;
+
+ if ((new_context = context_new(defaultcon)) == NULL)
+ goto fail_set;
+
+ if (env_params && (env = pam_getenv(pamh, "SELINUX_ROLE_REQUESTED")) != NULL && env[0] != '\0') {
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Requested role: %s", env);
+
+ if (get_default_type(env, &type)) {
+ pam_syslog(pamh, LOG_NOTICE, "No default type for role %s", env);
+ goto fail_set;
+ } else {
+ if (context_role_set(new_context, env))
+ goto fail_set;
+ if (context_type_set(new_context, type))
+ goto fail_set;
+ }
+ }
+
+ if (mls_enabled) {
+ if ((env = pam_getenv(pamh, "SELINUX_USE_CURRENT_RANGE")) != NULL && env[0] == '1') {
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "SELINUX_USE_CURRENT_RANGE is set");
+ use_current_range = 1;
+ }
+
+ if (use_current_range) {
+ security_context_t mycon = NULL;
+
+ if (getcon(&mycon) != 0)
+ goto fail_set;
+ my_context = context_new(mycon);
+ if (my_context == NULL) {
+ freecon(mycon);
+ goto fail_set;
+ }
+ freecon(mycon);
+ env = context_range_get(my_context);
+ } else {
+ env = pam_getenv(pamh, "SELINUX_LEVEL_REQUESTED");
+ }
+
+ if (env != NULL && env[0] != '\0') {
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Requested level: %s", env);
+ if (context_range_set(new_context, env))
+ goto fail_set;
+ }
+ }
+
+ newcon = strdup(context_str(new_context));
+ if (newcon == NULL)
+ goto fail_set;
+
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", newcon);
+
+ /* Get the string value of the context and see if it is valid. */
+ if (security_check_context(newcon)) {
+ pam_syslog(pamh, LOG_NOTICE, "Not a valid security context %s", newcon);
+ send_audit_message(pamh, 0, defaultcon, newcon);
+ freecon(newcon);
+ newcon = NULL;
+
+ goto fail_set;
+ }
+
+ /* we have to check that this user is allowed to go into the
+ range they have specified ... role is tied to an seuser, so that'll
+ be checked at setexeccon time */
+ if (mls_enabled && !mls_range_allowed(pamh, defaultcon, newcon, debug)) {
+ pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
+ send_audit_message(pamh, 0, defaultcon, newcon);
+ freecon(newcon);
+ newcon = NULL;
+ }
+
+ fail_set:
+ free(type);
+ context_free(my_context);
+ context_free(new_context);
+ send_audit_message(pamh, 0, defaultcon, NULL);
+ return newcon;
+}
+
static void
security_restorelabel_tty(const pam_handle_t *pamh,
const char *tty, security_context_t context)
@@ -439,13 +569,14 @@ PAM_EXTERN int
pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
int argc, const char **argv)
{
- int i, debug = 0, ttys=1, has_tty=isatty(0);
+ int i, debug = 0, ttys=1;
int verbose=0, close_session=0;
int select_context = 0;
int use_current_range = 0;
int ret = 0;
security_context_t* contextlist = NULL;
int num_contexts = 0;
+ int env_params = 0;
const char *username = NULL;
const void *tty = NULL;
char *seuser=NULL;
@@ -472,13 +603,16 @@ pam_sm_open_session(pam_handle_t *pamh,
if (strcmp(argv[i], "use_current_range") == 0) {
use_current_range = 1;
}
+ if (strcmp(argv[i], "env_params") == 0) {
+ env_params = 1;
+ }
}
if (debug)
pam_syslog(pamh, LOG_NOTICE, "Open Session");
- if (select_context && use_current_range) {
- pam_syslog(pamh, LOG_ERR, "select_context cannot be used with use_current_range");
+ if (select_context && env_params) {
+ pam_syslog(pamh, LOG_ERR, "select_context cannot be used with env_params");
select_context = 0;
}
@@ -510,12 +644,17 @@ pam_sm_open_session(pam_handle_t *pamh,
freeconary(contextlist);
if (default_user_context == NULL) {
pam_syslog(pamh, LOG_ERR, "Out of memory");
- return PAM_AUTH_ERR;
+ return PAM_BUF_ERR;
}
+
user_context = default_user_context;
- if (select_context && has_tty) {
- user_context = config_context(pamh, default_user_context, debug);
- if (user_context == NULL) {
+ if (select_context) {
+ user_context = config_context(pamh, default_user_context, use_current_range, debug);
+ } else if (env_params || use_current_range) {
+ user_context = context_from_env(pamh, default_user_context, env_params, use_current_range, debug);
+ }
+
+ if (user_context == NULL) {
freecon(default_user_context);
pam_syslog(pamh, LOG_ERR, "Unable to get valid context for %s",
username);
@@ -524,11 +663,9 @@ pam_sm_open_session(pam_handle_t *pamh,
return PAM_AUTH_ERR;
else
return PAM_SUCCESS;
- }
- }
+ }
}
else {
- if (has_tty) {
user_context = manual_context(pamh,seuser,debug);
if (user_context == NULL) {
pam_syslog (pamh, LOG_ERR, "Unable to get valid context for %s",
@@ -538,59 +675,6 @@ pam_sm_open_session(pam_handle_t *pamh,
else
return PAM_SUCCESS;
}
- } else {
- pam_syslog (pamh, LOG_ERR,
- "Unable to get valid context for %s, No valid tty",
- username);
- if (security_getenforce() == 1)
- return PAM_AUTH_ERR;
- else
- return PAM_SUCCESS;
- }
- }
-
- if (use_current_range && is_selinux_mls_enabled()) {
- security_context_t process_context=NULL;
- if (getcon(&process_context) == 0) {
- context_t pcon, ucon;
- char *process_level=NULL;
- security_context_t orig_context;
-
- if (user_context)
- orig_context = user_context;
- else
- orig_context = default_user_context;
-
- pcon = context_new(process_context);
- freecon(process_context);
- process_level = strdup(context_range_get(pcon));
- context_free(pcon);
-
- if (debug)
- pam_syslog (pamh, LOG_DEBUG, "process level=%s", process_level);
-
- ucon = context_new(orig_context);
-
- context_range_set(ucon, process_level);
- free(process_level);
-
- if (!mls_range_allowed(pamh, orig_context, context_str(ucon), debug)) {
- send_text(pamh, _("Requested MLS level not in permitted range"), debug);
- /* even if default_user_context is NULL audit that anyway */
- send_audit_message(pamh, 0, default_user_context, context_str(ucon));
- context_free(ucon);
- return PAM_AUTH_ERR;
- }
-
- if (debug)
- pam_syslog (pamh, LOG_DEBUG, "adjusted context=%s", context_str(ucon));
-
- /* replace the user context with the level adjusted one */
- freecon(user_context);
- user_context = strdup(context_str(ucon));
-
- context_free(ucon);
- }
}
if (getexeccon(&prev_user_context)<0) {
@@ -613,7 +697,7 @@ pam_sm_open_session(pam_handle_t *pamh,
}
}
}
- if(ttys && tty ) {
+ if (ttys && tty) {
ttyn=strdup(tty);
ttyn_context=security_label_tty(pamh,ttyn,user_context);
}

View File

@ -1,679 +0,0 @@
diff -up Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.c.create Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.c
--- Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.c.create 2008-03-20 18:06:32.000000000 +0100
+++ Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.c 2008-04-03 17:32:28.000000000 +0200
@@ -32,6 +32,8 @@
* DEALINGS IN THE SOFTWARE.
*/
+#define _ATFILE_SOURCE
+
#include "pam_namespace.h"
#include "argv_parse.h"
@@ -78,11 +80,29 @@ static void del_polydir_list(struct poly
}
}
-static void cleanup_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
+static void unprotect_dirs(struct protect_dir_s *dir)
+{
+ struct protect_dir_s *next;
+
+ while (dir != NULL) {
+ umount(dir->dir);
+ free(dir->dir);
+ next = dir->next;
+ free(dir);
+ dir = next;
+ }
+}
+
+static void cleanup_polydir_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
{
del_polydir_list(data);
}
+static void cleanup_protect_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
+{
+ unprotect_dirs(data);
+}
+
static char *expand_variables(const char *orig, const char *var_names[], const char *var_values[])
{
const char *src = orig;
@@ -132,8 +152,8 @@ static char *expand_variables(const char
static int parse_create_params(char *params, struct polydir_s *poly)
{
- char *sptr;
- struct passwd *pwd;
+ char *next;
+ struct passwd *pwd = NULL;
struct group *grp;
poly->mode = (mode_t)ULONG_MAX;
@@ -144,28 +164,40 @@ static int parse_create_params(char *par
return 0;
params++;
- params = strtok_r(params, ",", &sptr);
- if (params == NULL)
- return 0;
+ next = strchr(params, ',');
+ if (next != NULL) {
+ *next = '\0';
+ next++;
+ }
- errno = 0;
- poly->mode = (mode_t)strtoul(params, NULL, 0);
- if (errno != 0) {
- poly->mode = (mode_t)ULONG_MAX;
+ if (*params != '\0') {
+ errno = 0;
+ poly->mode = (mode_t)strtoul(params, NULL, 0);
+ if (errno != 0) {
+ poly->mode = (mode_t)ULONG_MAX;
+ }
}
- params = strtok_r(NULL, ",", &sptr);
+ params = next;
if (params == NULL)
return 0;
+ next = strchr(params, ',');
+ if (next != NULL) {
+ *next = '\0';
+ next++;
+ }
- pwd = getpwnam(params); /* session modules are not reentrant */
- if (pwd == NULL)
- return -1;
- poly->owner = pwd->pw_uid;
-
- params = strtok_r(NULL, ",", &sptr);
- if (params == NULL) {
- poly->group = pwd->pw_gid;
+ if (*params != '\0') {
+ pwd = getpwnam(params); /* session modules are not reentrant */
+ if (pwd == NULL)
+ return -1;
+ poly->owner = pwd->pw_uid;
+ }
+
+ params = next;
+ if (params == NULL || *params == '\0') {
+ if (pwd != NULL)
+ poly->group = pwd->pw_gid;
return 0;
}
grp = getgrnam(params);
@@ -199,7 +231,7 @@ static int parse_method(char *method, st
struct instance_data *idata)
{
enum polymethod pm;
- char *sptr;
+ char *sptr = NULL;
static const char *method_names[] = { "user", "context", "level", "tmpdir",
"tmpfs", NULL };
static const char *flag_names[] = { "create", "noinit", "iscript",
@@ -921,10 +953,158 @@ fail:
return rc;
}
+static int protect_mount(int dfd, const char *path, struct instance_data *idata)
+{
+ struct protect_dir_s *dir = idata->protect_dirs;
+ char tmpbuf[64];
+
+ while (dir != NULL) {
+ if (strcmp(path, dir->dir) == 0) {
+ return 0;
+ }
+ dir = dir->next;
+ }
+
+ dir = calloc(1, sizeof(*dir));
+
+ if (dir == NULL) {
+ return -1;
+ }
+
+ dir->dir = strdup(path);
+
+ if (dir->dir == NULL) {
+ free(dir);
+ return -1;
+ }
+
+ snprintf(tmpbuf, sizeof(tmpbuf), "/proc/self/fd/%d", dfd);
+
+ if (idata->flags & PAMNS_DEBUG) {
+ pam_syslog(idata->pamh, LOG_INFO,
+ "Protect mount of %s over itself", path);
+ }
+
+ if (mount(tmpbuf, tmpbuf, NULL, MS_BIND, NULL) != 0) {
+ int save_errno = errno;
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Protect mount of %s failed: %m", tmpbuf);
+ free(dir->dir);
+ free(dir);
+ errno = save_errno;
+ return -1;
+ }
+
+ dir->next = idata->protect_dirs;
+ idata->protect_dirs = dir;
+
+ return 0;
+}
+
+static int protect_dir(const char *path, mode_t mode, int do_mkdir,
+ struct instance_data *idata)
+{
+ char *p = strdup(path);
+ char *d;
+ char *dir = p;
+ int dfd = AT_FDCWD;
+ int dfd_next;
+ int save_errno;
+ int flags = O_RDONLY;
+ int rv = -1;
+ struct stat st;
+
+ if (p == NULL) {
+ goto error;
+ }
+
+ if (*dir == '/') {
+ dfd = open("/", flags);
+ if (dfd == -1) {
+ goto error;
+ }
+ dir++; /* assume / is safe */
+ }
+
+ while ((d=strchr(dir, '/')) != NULL) {
+ *d = '\0';
+ dfd_next = openat(dfd, dir, flags);
+ if (dfd_next == -1) {
+ goto error;
+ }
+
+ if (dfd != AT_FDCWD)
+ close(dfd);
+ dfd = dfd_next;
+
+ if (fstat(dfd, &st) != 0) {
+ goto error;
+ }
+
+ if (flags & O_NOFOLLOW) {
+ /* we are inside user-owned dir - protect */
+ if (protect_mount(dfd, p, idata) == -1)
+ goto error;
+ } else if (st.st_uid != 0 || st.st_gid != 0 ||
+ (st.st_mode & S_IWOTH)) {
+ /* do not follow symlinks on subdirectories */
+ flags |= O_NOFOLLOW;
+ }
+
+ *d = '/';
+ dir = d + 1;
+ }
+
+ rv = openat(dfd, dir, flags);
+
+ if (rv == -1) {
+ if (!do_mkdir || mkdirat(dfd, dir, mode) != 0) {
+ goto error;
+ }
+ rv = openat(dfd, dir, flags);
+ }
+
+ if (rv != -1) {
+ if (fstat(rv, &st) != 0) {
+ save_errno = errno;
+ close(rv);
+ rv = -1;
+ errno = save_errno;
+ goto error;
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ close(rv);
+ errno = ENOTDIR;
+ rv = -1;
+ goto error;
+ }
+ }
+
+ if (flags & O_NOFOLLOW) {
+ /* we are inside user-owned dir - protect */
+ if (protect_mount(rv, p, idata) == -1) {
+ save_errno = errno;
+ close(rv);
+ rv = -1;
+ errno = save_errno;
+ }
+ }
+
+error:
+ save_errno = errno;
+ free(p);
+ if (dfd != AT_FDCWD)
+ close(dfd);
+ errno = save_errno;
+
+ return rv;
+}
+
static int check_inst_parent(char *ipath, struct instance_data *idata)
{
struct stat instpbuf;
char *inst_parent, *trailing_slash;
+ int dfd;
/*
* stat the instance parent path to make sure it exists
* and is a directory. Check that its mode is 000 (unless the
@@ -942,30 +1122,27 @@ static int check_inst_parent(char *ipath
if (trailing_slash)
*trailing_slash = '\0';
- if (stat(inst_parent, &instpbuf) < 0) {
- pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m", inst_parent);
- free(inst_parent);
- return PAM_SESSION_ERR;
- }
+ dfd = protect_dir(inst_parent, 0, 1, idata);
- /*
- * Make sure we are dealing with a directory
- */
- if (!S_ISDIR(instpbuf.st_mode)) {
- pam_syslog(idata->pamh, LOG_ERR, "Instance parent %s is not a dir",
- inst_parent);
+ if (dfd == -1 || fstat(dfd, &instpbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error creating or accessing instance parent %s, %m", inst_parent);
+ if (dfd != -1)
+ close(dfd);
free(inst_parent);
return PAM_SESSION_ERR;
}
if ((idata->flags & PAMNS_IGN_INST_PARENT_MODE) == 0) {
- if (instpbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) {
- pam_syslog(idata->pamh, LOG_ERR, "Mode of inst parent %s not 000",
+ if ((instpbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) || instpbuf.st_uid != 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Mode of inst parent %s not 000 or owner not root",
inst_parent);
+ close(dfd);
free(inst_parent);
return PAM_SESSION_ERR;
}
}
+ close(dfd);
free(inst_parent);
return PAM_SUCCESS;
}
@@ -1051,6 +1228,8 @@ static int create_polydir(struct polydir
security_context_t dircon, oldcon = NULL;
#endif
const char *dir = polyptr->dir;
+ uid_t uid;
+ gid_t gid;
if (polyptr->mode != (mode_t)ULONG_MAX)
mode = polyptr->mode;
@@ -1077,8 +1256,8 @@ static int create_polydir(struct polydir
}
#endif
- rc = mkdir(dir, mode);
- if (rc != 0) {
+ rc = protect_dir(dir, mode, 1, idata);
+ if (rc == -1) {
pam_syslog(idata->pamh, LOG_ERR,
"Error creating directory %s: %m", dir);
return PAM_SESSION_ERR;
@@ -1098,36 +1277,41 @@ static int create_polydir(struct polydir
if (polyptr->mode != (mode_t)ULONG_MAX) {
/* explicit mode requested */
- if (chmod(dir, mode) != 0) {
+ if (fchmod(rc, mode) != 0) {
pam_syslog(idata->pamh, LOG_ERR,
"Error changing mode of directory %s: %m", dir);
+ close(rc);
+ umount(dir); /* undo the eventual protection bind mount */
rmdir(dir);
return PAM_SESSION_ERR;
}
}
- if (polyptr->owner != (uid_t)ULONG_MAX) {
- if (chown(dir, polyptr->owner, polyptr->group) != 0) {
- pam_syslog(idata->pamh, LOG_ERR,
- "Unable to change owner on directory %s: %m", dir);
- rmdir(dir);
- return PAM_SESSION_ERR;
- }
- if (idata->flags & PAMNS_DEBUG)
- pam_syslog(idata->pamh, LOG_DEBUG,
- "Polydir owner %u group %u from configuration", polyptr->owner, polyptr->group);
- } else {
- if (chown(dir, idata->uid, idata->gid) != 0) {
- pam_syslog(idata->pamh, LOG_ERR,
- "Unable to change owner on directory %s: %m", dir);
- rmdir(dir);
- return PAM_SESSION_ERR;
- }
- if (idata->flags & PAMNS_DEBUG)
- pam_syslog(idata->pamh, LOG_DEBUG,
- "Polydir owner %u group %u", idata->uid, idata->gid);
+ if (polyptr->owner != (uid_t)ULONG_MAX)
+ uid = polyptr->owner;
+ else
+ uid = idata->uid;
+
+ if (polyptr->group != (gid_t)ULONG_MAX)
+ gid = polyptr->group;
+ else
+ gid = idata->gid;
+
+ if (fchown(rc, uid, gid) != 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Unable to change owner on directory %s: %m", dir);
+ close(rc);
+ umount(dir); /* undo the eventual protection bind mount */
+ rmdir(dir);
+ return PAM_SESSION_ERR;
}
+ close(rc);
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Polydir owner %u group %u", uid, gid);
+
return PAM_SUCCESS;
}
@@ -1135,17 +1319,16 @@ static int create_polydir(struct polydir
* Create polyinstantiated instance directory (ipath).
*/
#ifdef WITH_SELINUX
-static int create_dirs(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
+static int create_instance(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
security_context_t icontext, security_context_t ocontext,
struct instance_data *idata)
#else
-static int create_dirs(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
+static int create_instance(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
struct instance_data *idata)
#endif
{
struct stat newstatbuf;
int fd;
- int newdir = 0;
/*
* Check to make sure instance parent is valid.
@@ -1171,7 +1354,7 @@ static int create_dirs(struct polydir_s
strcpy(ipath, polyptr->instance_prefix);
} else if (mkdir(ipath, S_IRUSR) < 0) {
if (errno == EEXIST)
- goto inst_init;
+ return PAM_IGNORE;
else {
pam_syslog(idata->pamh, LOG_ERR, "Error creating %s, %m",
ipath);
@@ -1179,7 +1362,6 @@ static int create_dirs(struct polydir_s
}
}
- newdir = 1;
/* Open a descriptor to it to prevent races */
fd = open(ipath, O_DIRECTORY | O_RDONLY);
if (fd < 0) {
@@ -1235,33 +1417,22 @@ static int create_dirs(struct polydir_s
return PAM_SESSION_ERR;
}
close(fd);
-
- /*
- * Check to see if there is a namespace initialization script in
- * the /etc/security directory. If such a script exists
- * execute it and pass directory to polyinstantiate and instance
- * directory as arguments.
- */
-
-inst_init:
- if (polyptr->flags & POLYDIR_NOINIT)
- return PAM_SUCCESS;
-
- return inst_init(polyptr, ipath, idata, newdir);
+ return PAM_SUCCESS;
}
/*
* This function performs the namespace setup for a particular directory
- * that is being polyinstantiated. It creates an MD5 hash of instance
- * directory, calls create_dirs to create it with appropriate
+ * that is being polyinstantiated. It calls poly_name to create name of instance
+ * directory, calls create_instance to mkdir it with appropriate
* security attributes, and performs bind mount to setup the process
* namespace.
*/
static int ns_setup(struct polydir_s *polyptr,
struct instance_data *idata)
{
- int retval = 0;
+ int retval;
+ int newdir = 1;
char *inst_dir = NULL;
char *instname = NULL;
struct stat statbuf;
@@ -1273,37 +1444,40 @@ static int ns_setup(struct polydir_s *po
pam_syslog(idata->pamh, LOG_DEBUG,
"Set namespace for directory %s", polyptr->dir);
- while (stat(polyptr->dir, &statbuf) < 0) {
- if (retval || !(polyptr->flags & POLYDIR_CREATE)) {
- pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
- polyptr->dir);
- return PAM_SESSION_ERR;
- } else {
- if (create_polydir(polyptr, idata) != PAM_SUCCESS)
- return PAM_SESSION_ERR;
- retval = PAM_SESSION_ERR; /* bail out on next failed stat */
- }
- }
+ retval = protect_dir(polyptr->dir, 0, 0, idata);
- /*
- * Make sure we are dealing with a directory
- */
- if (!S_ISDIR(statbuf.st_mode)) {
- pam_syslog(idata->pamh, LOG_ERR, "Polydir %s is not a dir",
+ if (retval < 0 && errno != ENOENT) {
+ pam_syslog(idata->pamh, LOG_ERR, "Polydir %s access error: %m",
polyptr->dir);
- return PAM_SESSION_ERR;
+ return PAM_SESSION_ERR;
}
+ if (retval < 0 && (polyptr->flags & POLYDIR_CREATE)) {
+ if (create_polydir(polyptr, idata) != PAM_SUCCESS)
+ return PAM_SESSION_ERR;
+ } else {
+ close(retval);
+ }
+
if (polyptr->method == TMPFS) {
if (mount("tmpfs", polyptr->dir, "tmpfs", 0, NULL) < 0) {
pam_syslog(idata->pamh, LOG_ERR, "Error mounting tmpfs on %s, %m",
polyptr->dir);
return PAM_SESSION_ERR;
}
- /* we must call inst_init after the mount in this case */
+
+ if (polyptr->flags & POLYDIR_NOINIT)
+ return PAM_SUCCESS;
+
return inst_init(polyptr, "tmpfs", idata, 1);
}
+ if (stat(polyptr->dir, &statbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error stating %s: %m",
+ polyptr->dir);
+ return PAM_SESSION_ERR;
+ }
+
/*
* Obtain the name of instance pathname based on the
* polyinstantiation method and instance context returned by
@@ -1341,14 +1515,18 @@ static int ns_setup(struct polydir_s *po
* contexts, owner, group and mode bits.
*/
#ifdef WITH_SELINUX
- retval = create_dirs(polyptr, inst_dir, &statbuf, instcontext,
+ retval = create_instance(polyptr, inst_dir, &statbuf, instcontext,
origcontext, idata);
#else
- retval = create_dirs(polyptr, inst_dir, &statbuf, idata);
+ retval = create_instance(polyptr, inst_dir, &statbuf, idata);
#endif
- if (retval < 0) {
- pam_syslog(idata->pamh, LOG_ERR, "Error creating instance dir");
+ if (retval == PAM_IGNORE) {
+ newdir = 0;
+ retval = PAM_SUCCESS;
+ }
+
+ if (retval != PAM_SUCCESS) {
goto error_out;
}
@@ -1363,6 +1541,9 @@ static int ns_setup(struct polydir_s *po
goto error_out;
}
+ if (!(polyptr->flags & POLYDIR_NOINIT))
+ retval = inst_init(polyptr, inst_dir, idata, newdir);
+
goto cleanup;
/*
@@ -1600,12 +1781,21 @@ static int setup_namespace(struct instan
}
}
out:
- if (retval != PAM_SUCCESS)
+ if (retval != PAM_SUCCESS) {
+ cleanup_tmpdirs(idata);
+ unprotect_dirs(idata->protect_dirs);
+ } else if (pam_set_data(idata->pamh, NAMESPACE_PROTECT_DATA, idata->protect_dirs,
+ cleanup_protect_data) != PAM_SUCCESS) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace protect data");
cleanup_tmpdirs(idata);
- else if (pam_set_data(idata->pamh, NAMESPACE_POLYDIR_DATA, idata->polydirs_ptr,
- cleanup_data) != PAM_SUCCESS) {
- pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace data");
+ unprotect_dirs(idata->protect_dirs);
+ return PAM_SYSTEM_ERR;
+ } else if (pam_set_data(idata->pamh, NAMESPACE_POLYDIR_DATA, idata->polydirs_ptr,
+ cleanup_polydir_data) != PAM_SUCCESS) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace polydir data");
cleanup_tmpdirs(idata);
+ pam_set_data(idata->pamh, NAMESPACE_PROTECT_DATA, NULL, NULL);
+ idata->protect_dirs = NULL;
return PAM_SYSTEM_ERR;
}
return retval;
@@ -1742,6 +1932,7 @@ PAM_EXTERN int pam_sm_open_session(pam_h
/* init instance data */
idata.flags = 0;
idata.polydirs_ptr = NULL;
+ idata.protect_dirs = NULL;
idata.pamh = pamh;
#ifdef WITH_SELINUX
if (is_selinux_enabled())
@@ -1893,6 +2084,7 @@ PAM_EXTERN int pam_sm_close_session(pam_
}
pam_set_data(idata.pamh, NAMESPACE_POLYDIR_DATA, NULL, NULL);
+ pam_set_data(idata.pamh, NAMESPACE_PROTECT_DATA, NULL, NULL);
return PAM_SUCCESS;
}
diff -up Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.h.create Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.h
--- Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.h.create 2008-02-13 13:49:44.000000000 +0100
+++ Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.h 2008-03-20 18:07:29.000000000 +0100
@@ -107,6 +107,7 @@
#define NAMESPACE_MAX_DIR_LEN 80
#define NAMESPACE_POLYDIR_DATA "pam_namespace:polydir_data"
+#define NAMESPACE_PROTECT_DATA "pam_namespace:protect_data"
/*
* Polyinstantiation method options, based on user, security context
@@ -156,9 +157,15 @@ struct polydir_s {
struct polydir_s *next; /* pointer to the next polydir entry */
};
+struct protect_dir_s {
+ char *dir; /* protected directory */
+ struct protect_dir_s *next; /* next entry */
+};
+
struct instance_data {
pam_handle_t *pamh; /* The pam handle for this instance */
struct polydir_s *polydirs_ptr; /* The linked list pointer */
+ struct protect_dir_s *protect_dirs; /* The pointer to stack of mount-protected dirs */
char user[LOGIN_NAME_MAX]; /* User name */
char ruser[LOGIN_NAME_MAX]; /* Requesting user name */
uid_t uid; /* The uid of the user */
@@ -166,3 +173,4 @@ struct instance_data {
uid_t ruid; /* The uid of the requesting user */
unsigned long flags; /* Flags for debug, selinux etc */
};
+
diff -up Linux-PAM-1.0.1/modules/pam_namespace/namespace.conf.5.xml.create Linux-PAM-1.0.1/modules/pam_namespace/namespace.conf.5.xml
--- Linux-PAM-1.0.1/modules/pam_namespace/namespace.conf.5.xml.create 2008-02-13 13:49:44.000000000 +0100
+++ Linux-PAM-1.0.1/modules/pam_namespace/namespace.conf.5.xml 2008-04-18 14:38:57.000000000 +0200
@@ -25,8 +25,8 @@
Directories can be polyinstantiated based on user name
or, in the case of SELinux, user name, sensitivity level or complete security context. If an
executable script <filename>/etc/security/namespace.init</filename>
- exists, it is used to initialize the namespace every time a new instance
- directory is setup. The script receives the polyinstantiated
+ exists, it is used to initialize the namespace every time an instance
+ directory is set up and mounted. The script receives the polyinstantiated
directory path and the instance directory path as its arguments.
</para>
diff -up Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.8.xml.create Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.8.xml
--- Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.8.xml.create 2008-02-13 13:49:44.000000000 +0100
+++ Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.8.xml 2008-04-18 14:40:54.000000000 +0200
@@ -64,11 +64,11 @@
provides a different instance of itself based on user name, or when
using SELinux, user name, security context or both. If an executable
script <filename>/etc/security/namespace.init</filename> exists, it
- is used to initialize the namespace every time a new instance
- directory is setup. The script receives the polyinstantiated
- directory path, the instance directory path, flag whether the instance
- directory was newly created (0 for no, 1 for yes), and the user name
- as its arguments.
+ is used to initialize the instance directory after it is set up
+ and mounted on the polyinstantiated direcory. The script receives the
+ polyinstantiated directory path, the instance directory path, flag
+ whether the instance directory was newly created (0 for no, 1 for yes),
+ and the user name as its arguments.
</para>
<para>

View File

@ -1,3 +1,27 @@
-------------------------------------------------------------------
Fri Mar 27 11:41:23 CET 2009 - kukuk@suse.de
- Update to version 1.0.91 aka 1.1 Beta2:
* Changes in the behavior of the password stack. Results of
PRELIM_CHECK are not used for the final run.
* Redefine LOCAL keyword of pam_access configuration file
* Add support for try_first_pass and use_first_pass to
pam_cracklib
* New password quality tests in pam_cracklib
* Add support for passing PAM_AUTHTOK to stdin of helpers from
pam_exec
* New options for pam_lastlog to show last failed login attempt and
to disable lastlog update
* New pam_pwhistory module to store last used passwords
* New pam_tally2 module similar to pam_tally with wordsize independent
tally data format, obsoletes pam_tally
* Make libpam not log missing module if its type is prepended with '-'
* New pam_timestamp module for authentication based on recent successful
login.
* Add blowfish support to pam_unix.
* Add support for user specific environment file to pam_env.
* Add pam_get_authtok to libpam as Linux-PAM extension.
-------------------------------------------------------------------
Wed Feb 11 01:20:15 CET 2009 - ro@suse.de

View File

@ -1,5 +1,5 @@
#
# spec file for package pam (Version 1.0.2)
# spec file for package pam (Version 1.0.91)
#
# Copyright (c) 2009 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
@ -17,7 +17,11 @@
# norootforbuild
%if %{suse_version} < 1110
%define enable_selinux 0
%else
%define enable_selinux 1
%endif
Name: pam
Url: http://www.kernel.org/pub/linux/libs/pam/
@ -28,9 +32,10 @@ BuildRequires: audit-devel
%if %{enable_selinux}
BuildRequires: libselinux-devel
%endif
%define libpam_so_version 0.81.12
%define libpam_misc_so_version 0.81.3
%define libpamc_so_version 0.81.0
BuildRequires: cracklib-dict-full pwdutils
%define libpam_so_version 0.82.1
%define libpam_misc_so_version 0.82.0
%define libpamc_so_version 0.82.0
License: BSD 3-Clause; GPL v2 or later
Group: System/Libraries
AutoReqProv: on
@ -39,11 +44,11 @@ AutoReqProv: on
Obsoletes: pam-64bit
%endif
#
Version: 1.0.2
Release: 19
Version: 1.0.91
Release: 1
Summary: A Security Tool that Provides Authentication for Applications
Source: Linux-PAM-%{version}.tar.bz2
Source1: Linux-PAM-%{version}-SUSE-docs.tar.bz2
Source1: Linux-PAM-%{version}-docs.tar.bz2
Source2: securetty
Source3: other.pamd
Source4: common-auth.pamd
@ -51,26 +56,9 @@ Source5: common-account.pamd
Source6: common-password.pamd
Source7: common-session.pamd
Source8: etc.environment
Patch: cvs.diff
Patch1: pam_tally-deprecated.diff
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Patch: Linux-PAM-docu.diff
Patch1: pam_tally.diff
Patch2: pam_xauth.diff
Patch3: pam_sepermit.diff
Patch4: pam-1.0.1-namespace-create.patch
Patch5: pam-1.0.0-selinux-env-params.patch
Patch6: Linux-PAM-docu-generated.diff
Patch7: pam_mail.diff
Patch8: pam_tally-fdleak.diff
Patch9: pam_pwhistory-0.1.diff
Patch10: pam_lastlog.diff
Patch11: pam_tally2.diff
Patch12: pam_cracklib-no-pwhistory.diff
Patch13: pam_xauth-XAUTHLOCALHOSTNAME.diff
Patch14: pam_pwhistory-type.diff
Patch15: pam_time.diff
Patch16: pam_limits-doc.diff
Patch17: pam_limits-logging.diff
Patch18: libpam-password-requisite.diff
%description
PAM (Pluggable Authentication Modules) is a system security tool that
@ -117,34 +105,11 @@ building both PAM-aware applications and modules for use with PAM.
%prep
%setup -q -n Linux-PAM-%{version} -b 1
%patch -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p0
%patch6 -p1
%patch7 -p0
%patch8 -p0
%patch9 -p0
chmod 755 modules/pam_pwhistory/tst-pam_pwhistory
%patch10 -p0
%patch11 -p1
chmod 755 modules/pam_tally2/tst-pam_tally2
%patch12 -p0
%patch13 -p0
%patch14 -p0
%patch15 -p0
%patch16 -p0
%patch17 -p0
%patch18 -p0
%patch -p0
%patch1 -p0
%build
aclocal -I m4 --install --force
libtoolize --force --automake --copy
automake --add-missing --copy
autoreconf
CFLAGS="$RPM_OPT_FLAGS" \
CFLAGS="$RPM_OPT_FLAGS -DNDEBUG" \
./configure \
--infodir=%{_infodir} \
--mandir=%{_mandir} \
@ -308,6 +273,7 @@ rm -rf $RPM_BUILD_ROOT
/%{_lib}/security/pam_tally.so
/%{_lib}/security/pam_tally2.so
/%{_lib}/security/pam_time.so
/%{_lib}/security/pam_timestamp.so
/%{_lib}/security/pam_tty_audit.so
/%{_lib}/security/pam_umask.so
/%{_lib}/security/pam_unix.so
@ -319,8 +285,10 @@ rm -rf $RPM_BUILD_ROOT
/%{_lib}/security/pam_warn.so
/%{_lib}/security/pam_wheel.so
/%{_lib}/security/pam_xauth.so
/sbin/mkhomedir_helper
/sbin/pam_tally
/sbin/pam_tally2
/sbin/pam_timestamp_check
%verify(not mode) %attr(4755,root,shadow) /sbin/unix_chkpwd
%attr(0700,root,root) /sbin/unix_update
@ -342,6 +310,27 @@ rm -rf $RPM_BUILD_ROOT
%{_libdir}/libpam_misc.so
%changelog
* Fri Mar 27 2009 kukuk@suse.de
- Update to version 1.0.91 aka 1.1 Beta2:
* Changes in the behavior of the password stack. Results of
PRELIM_CHECK are not used for the final run.
* Redefine LOCAL keyword of pam_access configuration file
* Add support for try_first_pass and use_first_pass to
pam_cracklib
* New password quality tests in pam_cracklib
* Add support for passing PAM_AUTHTOK to stdin of helpers from
pam_exec
* New options for pam_lastlog to show last failed login attempt and
to disable lastlog update
* New pam_pwhistory module to store last used passwords
* New pam_tally2 module similar to pam_tally with wordsize independent
tally data format, obsoletes pam_tally
* Make libpam not log missing module if its type is prepended with '-'
* New pam_timestamp module for authentication based on recent successful
login.
* Add blowfish support to pam_unix.
* Add support for user specific environment file to pam_env.
* Add pam_get_authtok to libpam as Linux-PAM extension.
* Wed Feb 11 2009 ro@suse.de
- use sr@latin instead of sr@Latn
* Thu Feb 05 2009 kukuk@suse.de

View File

@ -1,88 +0,0 @@
--- modules/pam_cracklib/pam_cracklib.8.xml
+++ modules/pam_cracklib/pam_cracklib.8.xml 2008/10/17 10:25:35
@@ -111,15 +111,6 @@
</para>
</listitem>
</varlistentry>
- <varlistentry>
- <term>Already used</term>
- <listitem>
- <para>
- Was the password used in the past? Previously used passwords
- are to be found in <filename>/etc/security/opasswd</filename>.
- </para>
- </listitem>
- </varlistentry>
</variablelist>
<para>
This module with no arguments will work well for standard unix
--- modules/pam_cracklib/pam_cracklib.c
+++ modules/pam_cracklib/pam_cracklib.c 2008/10/17 10:26:56
@@ -472,43 +472,6 @@
}
-#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
-
-static const char * check_old_password(const char *forwho, const char *newpass)
-{
- static char buf[16384];
- char *s_luser, *s_uid, *s_npas, *s_pas;
- const char *msg = NULL;
- FILE *opwfile;
-
- opwfile = fopen(OLD_PASSWORDS_FILE, "r");
- if (opwfile == NULL)
- return NULL;
-
- while (fgets(buf, 16380, opwfile)) {
- if (!strncmp(buf, forwho, strlen(forwho))) {
- char *sptr;
- buf[strlen(buf)-1] = '\0';
- s_luser = strtok_r(buf, ":,", &sptr);
- s_uid = strtok_r(NULL, ":,", &sptr);
- s_npas = strtok_r(NULL, ":,", &sptr);
- s_pas = strtok_r(NULL, ":,", &sptr);
- while (s_pas != NULL) {
- if (!strcmp(crypt(newpass, s_pas), s_pas)) {
- msg = _("has been already used");
- break;
- }
- s_pas = strtok_r(NULL, ":,", &sptr);
- }
- break;
- }
- }
- fclose(opwfile);
-
- return msg;
-}
-
-
static int _pam_unix_approve_pass(pam_handle_t *pamh,
unsigned int ctrl,
struct cracklib_options *opt,
@@ -516,7 +479,6 @@
const char *pass_new)
{
const char *msg = NULL;
- const void *user;
int retval;
if (pass_new == NULL || (pass_old && !strcmp(pass_old,pass_new))) {
@@ -532,15 +494,6 @@
* checking this would be the place
*/
msg = password_check(opt, pass_old, pass_new);
- if (!msg) {
- retval = pam_get_item(pamh, PAM_USER, &user);
- if (retval != PAM_SUCCESS || user == NULL) {
- if (ctrl & PAM_DEBUG_ARG)
- pam_syslog(pamh,LOG_ERR,"Can not get username");
- return PAM_AUTHTOK_ERR;
- }
- msg = check_old_password(user, pass_new);
- }
if (msg) {
if (ctrl & PAM_DEBUG_ARG)

View File

@ -1,325 +0,0 @@
2008-09-30 Tomas Mraz <t8m@centrum.cz>
* modules/pam_lastlog/pam_lastlog.8.xml: Document new options
noupdate and showfailed.
* modules/pam_lastlog/pam_lastlog.c(pam_parse): Recognize the new
options.
(last_login_read): New output parameter lltime. Do not display
the last login message if it would be empty.
(last_login_date): New output parameter lltime. Do not write the
last login info when LASTLOG_UPDATE is not set.
(last_login_failed): New function to display the last bad login
attempt from btmp.
(pam_sm_open_session): Obtain lltime from last_login_date() and
call last_login_failed() when appropriate.
--- modules/pam_lastlog/pam_lastlog.8.xml 9 Jun 2006 16:44:07 -0000 1.2
+++ modules/pam_lastlog/pam_lastlog.8.xml 30 Sep 2008 14:40:39 -0000 1.5
@@ -39,6 +39,12 @@
<arg choice="opt">
nowtmp
</arg>
+ <arg choice="opt">
+ noupdate
+ </arg>
+ <arg choice="opt">
+ showfailed
+ </arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -137,13 +143,35 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>noupdate</option>
+ </term>
+ <listitem>
+ <para>
+ Don't update any file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>showfailed</option>
+ </term>
+ <listitem>
+ <para>
+ Display number of failed login attempts and the date of the
+ last failed attempt from btmp. The date is not displayed
+ when <option>nodate</option> is specified.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
- <refsect1 id="pam_lastlog-services">
- <title>MODULE SERVICES PROVIDED</title>
+ <refsect1 id="pam_lastlog-types">
+ <title>MODULE TYPES PROVIDED</title>
<para>
- Only the <option>session</option> service is supported.
+ Only the <option>session</option> module type is provided.
</para>
</refsect1>
@@ -213,7 +241,7 @@
<refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
- <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
--- modules/pam_lastlog/pam_lastlog.c 24 Aug 2006 18:29:30 -0000 1.23
+++ modules/pam_lastlog/pam_lastlog.c 30 Sep 2008 14:40:39 -0000 1.24
@@ -46,6 +46,10 @@
};
#endif /* hpux */
+#ifndef _PATH_BTMP
+# define _PATH_BTMP "/var/log/btmp"
+#endif
+
/* XXX - time before ignoring lock. Is 1 sec enough? */
#define LASTLOG_IGNORE_LOCK_TIME 1
@@ -75,11 +79,13 @@
#define LASTLOG_DEBUG 020 /* send info to syslog(3) */
#define LASTLOG_QUIET 040 /* keep quiet about things */
#define LASTLOG_WTMP 0100 /* log to wtmp as well as lastlog */
+#define LASTLOG_BTMP 0200 /* display failed login info from btmp */
+#define LASTLOG_UPDATE 0400 /* update the lastlog and wtmp files (default) */
static int
_pam_parse(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
- int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE|LASTLOG_WTMP);
+ int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE|LASTLOG_WTMP|LASTLOG_UPDATE);
/* does the appliction require quiet? */
if (flags & PAM_SILENT) {
@@ -105,6 +111,10 @@
ctrl |= LASTLOG_NEVER;
} else if (!strcmp(*argv,"nowtmp")) {
ctrl &= ~LASTLOG_WTMP;
+ } else if (!strcmp(*argv,"noupdate")) {
+ ctrl &= ~(LASTLOG_WTMP|LASTLOG_UPDATE);
+ } else if (!strcmp(*argv,"showfailed")) {
+ ctrl |= LASTLOG_BTMP;
} else {
pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
}
@@ -135,7 +145,7 @@
}
static int
-last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid)
+last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid, time_t *lltime)
{
struct flock last_lock;
struct lastlog last_login;
@@ -166,6 +176,7 @@
last_lock.l_type = F_UNLCK;
(void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */
+ *lltime = last_login.ll_time;
if (!last_login.ll_time) {
if (announce & LASTLOG_DEBUG) {
pam_syslog(pamh, LOG_DEBUG,
@@ -216,8 +227,9 @@
}
}
- /* TRANSLATORS: "Last login: <date> from <host> on <terminal>" */
- retval = pam_info(pamh, _("Last login:%s%s%s"),
+ if (date != NULL || host != NULL || line != NULL)
+ /* TRANSLATORS: "Last login: <date> from <host> on <terminal>" */
+ retval = pam_info(pamh, _("Last login:%s%s%s"),
date ? date : "",
host ? host : "",
line ? line : "");
@@ -320,13 +332,13 @@
}
static int
-last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user)
+last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user, time_t *lltime)
{
int retval;
int last_fd;
/* obtain the last login date and all the relevant info */
- last_fd = open(_PATH_LASTLOG, O_RDWR);
+ last_fd = open(_PATH_LASTLOG, announce&LASTLOG_UPDATE ? O_RDWR : O_RDONLY);
if (last_fd < 0) {
if (errno == ENOENT) {
last_fd = open(_PATH_LASTLOG, O_RDWR|O_CREAT,
@@ -353,7 +365,7 @@
return PAM_SERVICE_ERR;
}
- retval = last_login_read(pamh, announce, last_fd, uid);
+ retval = last_login_read(pamh, announce, last_fd, uid, lltime);
if (retval != PAM_SUCCESS)
{
close(last_fd);
@@ -361,7 +373,9 @@
return retval;
}
- retval = last_login_write(pamh, announce, last_fd, uid, user);
+ if (announce & LASTLOG_UPDATE) {
+ retval = last_login_write(pamh, announce, last_fd, uid, user);
+ }
close(last_fd);
D(("all done with last login"));
@@ -369,6 +383,121 @@
return retval;
}
+static int
+last_login_failed(pam_handle_t *pamh, int announce, const char *user, time_t lltime)
+{
+ int retval;
+ int fd;
+ struct utmp ut;
+ struct utmp utuser;
+ int failed = 0;
+ char the_time[256];
+ char *date = NULL;
+ char *host = NULL;
+ char *line = NULL;
+
+ if (strlen(user) > UT_NAMESIZE) {
+ pam_syslog(pamh, LOG_WARNING, "username too long, output might be inaccurate");
+ }
+
+ /* obtain the failed login attempt records from btmp */
+ fd = open(_PATH_BTMP, O_RDONLY);
+ if (fd < 0) {
+ pam_syslog(pamh, LOG_ERR, "unable to open %s: %m", _PATH_BTMP);
+ D(("unable to open %s file", _PATH_BTMP));
+ return PAM_SERVICE_ERR;
+ }
+
+ while ((retval=pam_modutil_read(fd, (void *)&ut,
+ sizeof(ut))) == sizeof(ut)) {
+ if (ut.ut_tv.tv_sec >= lltime && strncmp(ut.ut_user, user, UT_NAMESIZE) == 0) {
+ memcpy(&utuser, &ut, sizeof(utuser));
+ failed++;
+ }
+ }
+
+ if (failed) {
+ /* we want the date? */
+ if (announce & LASTLOG_DATE) {
+ struct tm *tm, tm_buf;
+ time_t lf_time;
+
+ lf_time = utuser.ut_tv.tv_sec;
+ tm = localtime_r (&lf_time, &tm_buf);
+ strftime (the_time, sizeof (the_time),
+ /* TRANSLATORS: "strftime options for date of last login" */
+ _(" %a %b %e %H:%M:%S %Z %Y"), tm);
+
+ date = the_time;
+ }
+
+ /* we want & have the host? */
+ if ((announce & LASTLOG_HOST)
+ && (utuser.ut_host[0] != '\0')) {
+ /* TRANSLATORS: " from <host>" */
+ if (asprintf(&host, _(" from %.*s"), UT_HOSTSIZE,
+ utuser.ut_host) < 0) {
+ pam_syslog(pamh, LOG_ERR, "out of memory");
+ retval = PAM_BUF_ERR;
+ goto cleanup;
+ }
+ }
+
+ /* we want and have the terminal? */
+ if ((announce & LASTLOG_LINE)
+ && (utuser.ut_line[0] != '\0')) {
+ /* TRANSLATORS: " on <terminal>" */
+ if (asprintf(&line, _(" on %.*s"), UT_LINESIZE,
+ utuser.ut_line) < 0) {
+ pam_syslog(pamh, LOG_ERR, "out of memory");
+ retval = PAM_BUF_ERR;
+ goto cleanup;
+ }
+ }
+
+ if (line != NULL || date != NULL || host != NULL) {
+ /* TRANSLATORS: "Last failed login: <date> from <host> on <terminal>" */
+ pam_info(pamh, _("Last failed login:%s%s%s"),
+ date ? date : "",
+ host ? host : "",
+ line ? line : "");
+ }
+
+ _pam_drop(line);
+#if defined HAVE_DNGETTEXT && defined ENABLE_NLS
+ retval = asprintf (&line, dngettext(PACKAGE,
+ "There was %d failed login attempt since the last successful login.",
+ "There were %d failed login attempts since the last successful login.",
+ failed),
+ failed);
+#else
+ if (daysleft == 1)
+ retval = asprintf(&line,
+ _("There was %d failed login attempt since the last successful login."),
+ failed);
+ else
+ retval = asprintf(&line,
+ /* TRANSLATORS: only used if dngettext is not supported */
+ _("There were %d failed login attempts since the last successful login."),
+ failed);
+#endif
+ if (retval >= 0)
+ retval = pam_info(pamh, "%s", line);
+ else {
+ retval = PAM_BUF_ERR;
+ line = NULL;
+ }
+ }
+
+cleanup:
+ free(host);
+ free(line);
+ close(fd);
+ D(("all done with btmp"));
+
+ return retval;
+}
+
/* --- authentication management functions (only) --- */
PAM_EXTERN int
@@ -379,6 +508,7 @@
const void *user;
const struct passwd *pwd;
uid_t uid;
+ time_t lltime = 0;
/*
* this module gets the uid of the PAM_USER. Uses it to display
@@ -407,7 +537,11 @@
/* process the current login attempt (indicate last) */
- retval = last_login_date(pamh, ctrl, uid, user);
+ retval = last_login_date(pamh, ctrl, uid, user, &lltime);
+
+ if ((ctrl & LASTLOG_BTMP) && retval == PAM_SUCCESS) {
+ retval = last_login_failed(pamh, ctrl, user, lltime);
+ }
/* indicate success or failure */

View File

@ -1,23 +0,0 @@
--- modules/pam_limits/limits.conf.5.xml
+++ modules/pam_limits/limits.conf.5.xml 2008/11/27 14:25:16
@@ -230,6 +230,11 @@
</variablelist>
<para>
+ All items support the values <emphasis>-1</emphasis>,
+ <emphasis>unlimited</emphasis> or <emphasis>infinity</emphasis> indicating no limit,
+ except for <emphasis remap='B'>priority</emphasis> and <emphasis remap='B'>nice</emphasis>.
+ </para>
+ <para>
In general, individual limits have priority over group limits, so if
you impose no limits for <emphasis>admin</emphasis> group, but one of
the members in this group have a limits line, the user will have its
@@ -275,6 +280,7 @@
<citerefentry><refentrytitle>pam_limits</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>getrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry>
</para>
</refsect1>

View File

@ -1,125 +0,0 @@
--- modules/pam_limits/pam_limits.c 7 Dec 2007 15:40:02 -0000 1.46
+++ modules/pam_limits/pam_limits.c 5 Feb 2009 15:48:49 -0000
@@ -42,7 +42,7 @@
#include <locale.h>
#ifdef HAVE_LIBAUDIT
-#include <libaudit.h>
+#include <libaudit.h>
#endif
/* Module defines */
@@ -141,6 +141,73 @@
return ctrl;
}
+static const char *
+i2str (int i)
+{
+ switch (i) {
+ case RLIMIT_CPU:
+ return "cpu";
+ break;
+ case RLIMIT_FSIZE:
+ return "fsize";
+ break;
+ case RLIMIT_DATA:
+ return "data";
+ break;
+ case RLIMIT_STACK:
+ return "stack";
+ break;
+ case RLIMIT_CORE:
+ return "core";
+ break;
+ case RLIMIT_RSS:
+ return "rss";
+ break;
+ case RLIMIT_NPROC:
+ return "nproc";
+ break;
+ case RLIMIT_NOFILE:
+ return "nofile";
+ break;
+ case RLIMIT_MEMLOCK:
+ return "memlock";
+ break;
+#ifdef RLIMIT_AS
+ case RLIMIT_AS:
+ return "as";
+ break;
+#endif
+#ifdef RLIMIT_LOCKS
+ case RLIMIT_LOCKS:
+ return "locks";
+ break;
+#endif
+#ifdef RLIMIT_SIGPENDING
+ case RLIMIT_SIGPENDING:
+ return "sigpending";
+ break;
+#endif
+#ifdef RLIMIT_MSGQUEUE
+ case RLIMIT_MSGQUEUE:
+ return "msgqueue";
+ break;
+#endif
+#ifdef RLIMIT_NICE
+ case RLIMIT_NICE:
+ return "nice";
+ break;
+#endif
+#ifdef RLIMIT_RTPRIO
+ case RLIMIT_RTPRIO:
+ return "rtprio";
+ break;
+#endif
+ default:
+ return "UNKNOWN";
+ break;
+ }
+}
+
#define LIMITED_OK 0 /* limit setting appeared to work */
#define LIMIT_ERR 1 /* error setting a limit */
@@ -416,8 +483,8 @@
if (int_value < -20)
int_value = -20;
rlimit_value = 20 - int_value;
-#endif
break;
+#endif
}
if ( (limit_item != LIMIT_LOGIN)
@@ -575,6 +642,8 @@
int retval = LIMITED_OK;
for (i=0, status=LIMITED_OK; i<RLIM_NLIMITS; i++) {
+ int res;
+
if (!pl->limits[i].supported) {
/* skip it if its not known to the system */
continue;
@@ -586,7 +655,11 @@
}
if (pl->limits[i].limit.rlim_cur > pl->limits[i].limit.rlim_max)
pl->limits[i].limit.rlim_cur = pl->limits[i].limit.rlim_max;
- status |= setrlimit(i, &pl->limits[i].limit);
+ res = setrlimit(i, &pl->limits[i].limit);
+ if (res != 0)
+ pam_syslog(pamh, LOG_ERR, "Could not set limit for '%s': %m",
+ i2str(i));
+ status |= res;
}
if (status) {
@@ -595,6 +668,7 @@
status = setpriority(PRIO_PROCESS, 0, pl->priority);
if (status != 0) {
+ pam_syslog(pamh, LOG_ERR, "Could not set limit for PRIO_PROCESS: %m");
retval = LIMIT_ERR;
}

View File

@ -1,49 +0,0 @@
2008-09-25 Thorsten Kukuk <kukuk@thkukuk.de>
* modules/pam_mail/pam_mail.c (report_mail): Fix logic of
"quiet" option (Patch from Andreas Henriksson <andreas@fatal.se>)
* modules/pam_mail/pam_mail.8.xml: Fix typo.
diff -u -r1.5 pam_mail.8.xml
--- modules/pam_mail/pam_mail.8.xml 18 Aug 2008 13:29:24 -0000 1.5
+++ modules/pam_mail/pam_mail.8.xml 25 Sep 2008 11:51:29 -0000
@@ -40,7 +40,7 @@
nopen
</arg>
<arg choice="opt">
- quit
+ quiet
</arg>
<arg choice="opt">
standard
--- modules/pam_mail/pam_mail.c 30 Apr 2007 10:56:24 -0000 1.19
+++ modules/pam_mail/pam_mail.c 25 Sep 2008 11:51:29 -0000
@@ -303,8 +303,13 @@
{
int retval;
- if (!(ctrl & PAM_MAIL_SILENT) ||
- ((ctrl & PAM_QUIET_MAIL) && type == HAVE_NEW_MAIL))
+ if ((ctrl & PAM_MAIL_SILENT) ||
+ ((ctrl & PAM_QUIET_MAIL) && type != HAVE_NEW_MAIL))
+ {
+ D(("keeping quiet"));
+ retval = PAM_SUCCESS;
+ }
+ else
{
if (ctrl & PAM_STANDARD_MAIL)
switch (type)
@@ -345,11 +350,6 @@
break;
}
}
- else
- {
- D(("keeping quiet"));
- retval = PAM_SUCCESS;
- }
D(("returning %s", pam_strerror(pamh, retval)));
return retval;

File diff suppressed because it is too large Load Diff

View File

@ -1,102 +0,0 @@
Index: modules/pam_pwhistory/pam_pwhistory.8.xml
===================================================================
RCS file: /cvsroot/pam/Linux-PAM/modules/pam_pwhistory/pam_pwhistory.8.xml,v
retrieving revision 1.1
diff -u -r1.1 pam_pwhistory.8.xml
--- modules/pam_pwhistory/pam_pwhistory.8.xml 10 Oct 2008 06:53:45 -0000 1.1
+++ modules/pam_pwhistory/pam_pwhistory.8.xml 19 Nov 2008 14:24:00 -0000
@@ -33,6 +33,9 @@
<arg choice="opt">
retry=<replaceable>N</replaceable>
</arg>
+ <arg choice="opt">
+ type=<replaceable>STRING</replaceable>
+ </arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -119,6 +122,21 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>type=<replaceable>STRING</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The default action is for the module to use the
+ following prompts when requesting passwords:
+ "New UNIX password: " and "Retype UNIX password: ".
+ The default word <emphasis>UNIX</emphasis> can
+ be replaced with this option.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
Index: modules/pam_pwhistory/pam_pwhistory.c
===================================================================
RCS file: /cvsroot/pam/Linux-PAM/modules/pam_pwhistory/pam_pwhistory.c,v
retrieving revision 1.1
diff -u -r1.1 pam_pwhistory.c
--- modules/pam_pwhistory/pam_pwhistory.c 10 Oct 2008 06:53:45 -0000 1.1
+++ modules/pam_pwhistory/pam_pwhistory.c 19 Nov 2008 14:24:00 -0000
@@ -58,7 +58,9 @@
#include "opasswd.h"
+/* For Translators: "%s%s" could be replaced with "<service> " or "". */
#define NEW_PASSWORD_PROMPT _("New %s%spassword: ")
+/* For Translators: "%s%s" could be replaced with "<service> " or "". */
#define AGAIN_PASSWORD_PROMPT _("Retype new %s%spassword: ")
#define MISTYPED_PASSWORD _("Sorry, passwords do not match.")
@@ -70,6 +72,7 @@
int enforce_for_root;
int remember;
int tries;
+ const char *prompt_type;
};
typedef struct options_t options_t;
@@ -101,6 +104,8 @@
}
else if (strcasecmp (argv, "enforce_for_root") == 0)
options->enforce_for_root = 1;
+ else if (strncasecmp (argv, "type=", 5) == 0)
+ options->prompt_type = &argv[5];
else
pam_syslog (pamh, LOG_ERR, "pam_pwhistory: unknown option: %s", argv);
}
@@ -121,6 +126,7 @@
/* Set some default values, which could be overwritten later. */
options.remember = 10;
options.tries = 1;
+ options.prompt_type = "UNIX";
/* Parse parameters for module */
for ( ; argc-- > 0; argv++)
@@ -209,7 +215,8 @@
while ((newpass == NULL) && (tries++ < options.tries))
{
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &newpass,
- NEW_PASSWORD_PROMPT, "UNIX", " ");
+ NEW_PASSWORD_PROMPT, options.prompt_type,
+ strlen (options.prompt_type) > 0?" ":"");
if (retval != PAM_SUCCESS)
{
_pam_drop (newpass);
@@ -249,7 +256,9 @@
char *new2;
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &new2,
- AGAIN_PASSWORD_PROMPT, "UNIX", " ");
+ AGAIN_PASSWORD_PROMPT,
+ options.prompt_type,
+ strlen (options.prompt_type) > 0?" ":"");
if (retval != PAM_SUCCESS)
return retval;

View File

@ -1,17 +0,0 @@
2008-04-17 Tomas Mraz <t8m@centrum.cz>
* modules/pam_sepermit/pam_sepermit.c(sepermit_match): Do not try
to lock if euid != 0.
--- Linux-PAM-1.0/modules/pam_sepermit/pam_sepermit.c 2008-03-31 12:31:50.000000000 +0200
+++ Linux-PAM/modules/pam_sepermit/pam_sepermit.c 2008-04-17 16:29:02.000000000 +0200
@@ -305,7 +305,7 @@
free(line);
fclose(f);
if (matched)
- return exclusive ? sepermit_lock(pamh, user, debug) : 0;
+ return (geteuid() == 0 && exclusive) ? sepermit_lock(pamh, user, debug) : 0;
else
return -1;
}

55
pam_tally-deprecated.diff Normal file
View File

@ -0,0 +1,55 @@
--- modules/pam_tally/pam_tally.8.xml
+++ modules/pam_tally/pam_tally.8.xml 2009/03/27 10:49:17
@@ -81,7 +81,13 @@
<para>
This module maintains a count of attempted accesses, can
- reset count on success, can deny access if too many attempts fail.
+ reset count on success, can deny access if too many attempts
+ fail.
+ </para>
+ <para>
+ pam_tally has several limitations, which are solved with
+ pam_tally2. For this reason pam_tally is deprecated and
+ will be removed in a future release.
</para>
<para>
pam_tally comes in two parts:
--- modules/pam_tally/pam_tally.c
+++ modules/pam_tally/pam_tally.c 2009/03/27 10:52:56
@@ -630,6 +630,8 @@
const char
*user;
+ pam_syslog (pamh, LOG_INFO, "pam_tally is deprecated and obsoleted by pam_tally2");
+
rvcheck = tally_parse_args(pamh, opts, PHASE_AUTH, argc, argv);
if ( rvcheck != PAM_SUCCESS )
RETURN_ERROR( rvcheck );
@@ -664,6 +666,8 @@
const char
*user;
+ pam_syslog (pamh, LOG_INFO, "pam_tally is deprecated and obsoleted by pam_tally2");
+
rv = tally_parse_args(pamh, opts, PHASE_AUTH, argc, argv);
if ( rv != PAM_SUCCESS )
RETURN_ERROR( rv );
@@ -709,6 +713,8 @@
const char
*user;
+ pam_syslog (pamh, LOG_INFO, "pam_tally is deprecated and obsoleted by pam_tally2");
+
rv = tally_parse_args(pamh, opts, PHASE_ACCOUNT, argc, argv);
if ( rv != PAM_SUCCESS )
RETURN_ERROR( rv );
@@ -815,6 +821,8 @@
exit(0);
}
+ fprintf (stderr, "\npam_tally is deprecated and pam_tally2 should be used instead\n\n");
+
umask(077);
/*

View File

@ -1,37 +0,0 @@
2008-09-25 Tomas Mraz <t8m@centrum.cz>
* modules/pam_tally/pam_tally.c(get_tally): Fix syslog message.
(tally_check): Open faillog read only. Close file descriptor.
Fix typos in messages.
--- modules/pam_tally/pam_tally.c 9 Jul 2008 12:23:23 -0000 1.30
+++ modules/pam_tally/pam_tally.c 19 Sep 2008 12:29:21 -0000
@@ -350,7 +350,7 @@ get_tally(pam_handle_t *pamh, tally_t *t
}
if ( ! ( *TALLY = fopen(filename,(*tally!=TALLY_HI)?"r+":"r") ) ) {
- pam_syslog(pamh, LOG_ALERT, "Error opening %s for update", filename);
+ pam_syslog(pamh, LOG_ALERT, "Error opening %s for %s", filename, *tally!=TALLY_HI?"update":"read");
/* Discovering why account service fails: e/uid are target user.
*
@@ -504,7 +504,7 @@ tally_check (time_t oldtime, pam_handle_
tally_t
deny = opts->deny;
tally_t
- tally = 0; /* !TALLY_HI --> Log opened for update */
+ tally = TALLY_HI;
long
lock_time = opts->lock_time;
@@ -515,6 +515,10 @@ tally_check (time_t oldtime, pam_handle_
i=get_tally(pamh, &tally, uid, opts->filename, &TALLY, fsp);
if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); }
+ if ( TALLY != NULL ) {
+ fclose(TALLY);
+ }
+
if ( !(opts->ctrl & OPT_MAGIC_ROOT) || getuid() ) { /* magic_root skips tally check */
/* To deny or not to deny; that is the question */

View File

@ -1,173 +0,0 @@
2008-07-09 Thorsten Kukuk <kukuk@thkukuk.de>
* modules/pam_tally/pam_tally.c: Add support for silent and
no_log_info options.
* modules/pam_tally/pam_tally.8.xml: Document silent and
no_log_info options.
--- Linux-PAM-1.0/modules/pam_tally/pam_tally.8.xml 2007-10-10 16:10:07.000000000 +0200
+++ Linux-PAM/modules/pam_tally/pam_tally.8.xml 2008-08-20 20:56:28.000000000 +0200
@@ -51,6 +51,12 @@
<arg choice="opt">
audit
</arg>
+ <arg choice="opt">
+ silent
+ </arg>
+ <arg choice="opt">
+ no_log_info
+ </arg>
</cmdsynopsis>
<cmdsynopsis id="pam_tally-cmdsynopsis2">
<command>pam_tally</command>
@@ -150,6 +156,26 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>silent</option>
+ </term>
+ <listitem>
+ <para>
+ Don't print informative messages.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>no_log_info</option>
+ </term>
+ <listitem>
+ <para>
+ Don't log informative messages via <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</listitem>
</varlistentry>
--- Linux-PAM-1.0/modules/pam_tally/pam_tally.c 2007-11-20 11:58:11.000000000 +0100
+++ Linux-PAM/modules/pam_tally/pam_tally.c 2008-07-16 10:09:02.000000000 +0200
@@ -97,6 +97,8 @@
#define OPT_NO_LOCK_TIME 020
#define OPT_NO_RESET 040
#define OPT_AUDIT 0100
+#define OPT_SILENT 0200
+#define OPT_NOLOGNOTICE 0400
/*---------------------------------------------------------------------*/
@@ -205,6 +207,12 @@
else if ( ! strcmp ( *argv, "audit") ) {
opts->ctrl |= OPT_AUDIT;
}
+ else if ( ! strcmp ( *argv, "silent") ) {
+ opts->ctrl |= OPT_SILENT;
+ }
+ else if ( ! strcmp ( *argv, "no_log_info") ) {
+ opts->ctrl |= OPT_NOLOGNOTICE;
+ }
else {
pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
}
@@ -524,12 +532,17 @@
{
if ( lock_time + oldtime > time(NULL) )
{
- pam_syslog(pamh, LOG_NOTICE,
- "user %s (%lu) has time limit [%lds left]"
- " since last failure.",
- user, (unsigned long int) uid,
- oldtime+lock_time
- -time(NULL));
+ if (!(opts->ctrl & OPT_SILENT))
+ pam_info (pamh,
+ _("Account temporary locked (%lds seconds left)"),
+ oldtime+lock_time-time(NULL));
+
+ if (!(opts->ctrl & OPT_NOLOGNOTICE))
+ pam_syslog (pamh, LOG_NOTICE,
+ "user %s (%lu) has time limit [%lds left]"
+ " since last failure.",
+ user, (unsigned long int) uid,
+ oldtime+lock_time-time(NULL));
return PAM_AUTH_ERR;
}
}
@@ -545,9 +558,14 @@
( tally > deny ) && /* tally>deny means exceeded */
( ((opts->ctrl & OPT_DENY_ROOT) || uid) ) /* even_deny stops uid check */
) {
- pam_syslog(pamh, LOG_NOTICE,
- "user %s (%lu) tally "TALLY_FMT", deny "TALLY_FMT,
- user, (unsigned long int) uid, tally, deny);
+ if (!(opts->ctrl & OPT_SILENT))
+ pam_info (pamh, _("Accounted locked due to "TALLY_FMT" failed login"),
+ tally);
+
+ if (!(opts->ctrl & OPT_NOLOGNOTICE))
+ pam_syslog(pamh, LOG_NOTICE,
+ "user %s (%lu) tally "TALLY_FMT", deny "TALLY_FMT,
+ user, (unsigned long int) uid, tally, deny);
return PAM_AUTH_ERR; /* Only unconditional failure */
}
}
@@ -594,7 +612,7 @@
#ifdef PAM_SM_AUTH
PAM_EXTERN int
-pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+pam_sm_authenticate(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
int
@@ -612,6 +630,9 @@
if ( rvcheck != PAM_SUCCESS )
RETURN_ERROR( rvcheck );
+ if (flags & PAM_SILENT)
+ opts->ctrl |= OPT_SILENT;
+
rvcheck = pam_get_uid(pamh, &uid, &user, opts);
if ( rvcheck != PAM_SUCCESS )
RETURN_ERROR( rvcheck );
@@ -625,7 +646,7 @@
}
PAM_EXTERN int
-pam_sm_setcred(pam_handle_t *pamh, int flags UNUSED,
+pam_sm_setcred(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
int
@@ -643,6 +664,9 @@
if ( rv != PAM_SUCCESS )
RETURN_ERROR( rv );
+ if (flags & PAM_SILENT)
+ opts->ctrl |= OPT_SILENT;
+
rv = pam_get_uid(pamh, &uid, &user, opts);
if ( rv != PAM_SUCCESS )
RETURN_ERROR( rv );
@@ -667,7 +691,7 @@
/* To reset failcount of user on successfull login */
PAM_EXTERN int
-pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED,
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
int
@@ -685,6 +709,9 @@
if ( rv != PAM_SUCCESS )
RETURN_ERROR( rv );
+ if (flags & PAM_SILENT)
+ opts->ctrl |= OPT_SILENT;
+
rv = pam_get_uid(pamh, &uid, &user, opts);
if ( rv != PAM_SUCCESS )
RETURN_ERROR( rv );

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +0,0 @@
2008-11-25 Thorsten Kukuk <kukuk@thkukuk.de>
* modules/pam_time/pam_time.c (is_same): Fix check
of correct string length (debian bug #326407).
--- modules/pam_time/pam_time.c 7 Dec 2007 15:40:02 -0000 1.16
+++ modules/pam_time/pam_time.c 25 Nov 2008 13:37:12 -0000
@@ -358,8 +358,8 @@
/* Ok, we know that b is a substring from A and does not contain
wildcards, but now the length of both strings must be the same,
- too. */
- if (strlen (a) != strlen(b))
+ too. In this case it means, a[i] has to be the end of the string. */
+ if (a[i] != '\0')
return FALSE;
return ( !len );

View File

@ -1,54 +0,0 @@
--- modules/pam_xauth/pam_xauth.c 8 Apr 2008 07:01:41 -0000 1.16
+++ modules/pam_xauth/pam_xauth.c 18 Nov 2008 12:30:58 -0000
@@ -280,7 +280,7 @@
return noent_code;
default:
if (debug) {
- pam_syslog(pamh, LOG_ERR,
+ pam_syslog(pamh, LOG_DEBUG,
"error opening %s: %m", path);
}
return PAM_PERM_DENIED;
@@ -293,7 +293,8 @@
int argc, const char **argv)
{
char *cookiefile = NULL, *xauthority = NULL,
- *cookie = NULL, *display = NULL, *tmp = NULL;
+ *cookie = NULL, *display = NULL, *tmp = NULL,
+ *xauthlocalhostname = NULL;
const char *user, *xauth = NULL;
struct passwd *tpwd, *rpwd;
int fd, i, debug = 0;
@@ -588,14 +589,30 @@
if (asprintf(&d, "DISPLAY=%s", display) < 0)
{
- pam_syslog(pamh, LOG_DEBUG, "out of memory");
+ pam_syslog(pamh, LOG_ERR, "out of memory");
cookiefile = NULL;
retval = PAM_SESSION_ERR;
goto cleanup;
}
if (pam_putenv (pamh, d) != PAM_SUCCESS)
- pam_syslog (pamh, LOG_DEBUG,
+ pam_syslog (pamh, LOG_ERR,
+ "can't set environment variable '%s'", d);
+ free (d);
+ }
+
+ /* set XAUTHLOCALHOSTNAME to make sure that su - work under gnome */
+ if ((xauthlocalhostname = getenv("XAUTHLOCALHOSTNAME")) != NULL) {
+ char *d;
+
+ if (asprintf(&d, "XAUTHLOCALHOSTNAME=%s", xauthlocalhostname) < 0) {
+ pam_syslog(pamh, LOG_ERR, "out of memory");
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+
+ if (pam_putenv (pamh, d) != PAM_SUCCESS)
+ pam_syslog (pamh, LOG_ERR,
"can't set environment variable '%s'", d);
free (d);
}

View File

@ -1,26 +0,0 @@
2008-04-08 Tomas Mraz <t8m@centrum.cz>
* modules/pam_xauth/pam_xauth.c(run_coprocess): Avoid multiple
calls to sysconf() (based on patch by Sami Farin).
--- Linux-PAM-1.0/modules/pam_xauth/pam_xauth.c 2007-10-01 11:41:32.000000000 +0200
+++ Linux-PAM/modules/pam_xauth/pam_xauth.c 2008-06-22 09:47:33.000000000 +0200
@@ -118,6 +118,7 @@
size_t j;
char *args[10];
const char *tmp;
+ int maxopened;
/* Drop privileges. */
setgid(gid);
setgroups(0, NULL);
@@ -129,7 +130,8 @@
* descriptors. */
dup2(ipipe[0], STDIN_FILENO);
dup2(opipe[1], STDOUT_FILENO);
- for (i = 0; i < sysconf(_SC_OPEN_MAX); i++) {
+ maxopened = (int)sysconf(_SC_OPEN_MAX);
+ for (i = 0; i < maxopened; i++) {
if ((i != STDIN_FILENO) && (i != STDOUT_FILENO)) {
close(i);
}