PAM and return of init_session ignored ?

aurel <[email protected]>
Newsgroups gmane.comp.tools.sudo.devel
Message-ID <[email protected]>
Hi,

I'm developing a PAM module for/auth/  and/session/. When my module return PAM_AUTH_ERR
to sudoers, the command is not executed. But when the/session/  return PAM_SESSION_ERR,
the command is executed anyway. Why ?

However, in source code (sudo-1.8.10p3), a session error causes EXIT_FAILURE in parent before forking.
But the macro AUTH_FAILURE and AUTH_FATALdo not have the same value  (see the comments) :


(sudo/plugins/sudoers/auth/pam.c)

|sudo_pam_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth)||
||{||
||	...||
	
||	if (def_pam_session) {
         *pam_status = pam_open_session(pamh, 0);
         if (*pam_status != PAM_SUCCESS) {   /* PAM_SUCCESS = 0 */
             (void) pam_end(pamh, *pam_status | PAM_DATA_SILENT);
             pamh = NULL;
             status = AUTH_FAILURE;  /* AUTH_FAILURE = 1 */
             goto done;
         }
     }

	...
	done:		
||  	    debug_return_int(status);||   /* return 1 */
||}|



called by
(sudo/plugins/sudoers/auth/sudo_auth.c)

|static sudo_auth auth_switch[] = {||
||/* Standalone entries first */||
||#ifdef HAVE_PAM||
||     AUTH_ENTRY("pam", FLAG_STANDALONE, sudo_pam_init, NULL, sudo_pam_verify, sudo_pam_cleanup, sudo_pam_begin_session, sudo_pam_end_session)||
||#endif||
||	...||
||}||
|...
  |int sudo_auth_begin_session(struct passwd *pw, char **user_env[])||
||{||
||     sudo_auth *auth;||
||     int status = AUTH_SUCCESS;||
||     debug_decl(sudo_auth_begin_session, SUDO_DEBUG_AUTH)||
||
||     for (auth = auth_switch; auth->name; auth++) {||
||         if (auth->begin_session && !IS_DISABLED(auth)) {||
||             status = (auth->begin_session)(pw, user_env, auth);  /* call|||||sudo_pam_begin_session|  */
||             if (status == AUTH_FATAL) /* AUTH_FATAL = 3  ???!!! if|||sudo_pam_begin_session return error (1) status = 1|*/||
||                 break;          /* assume error msg already printed */||
||         }||
||     }||
||     debug_return_int(status == AUTH_FATAL ? -1 : 1);  /* So always return 1 ?! */||
||}||
|


called by
(sudo/plugins/sudoers/policy.c)

|static int||
||sudoers_policy_init_session(struct passwd *pwd, char **user_env[])||
||{||
||     debug_decl(sudoers_policy_init_session, SUDO_DEBUG_PLUGIN)||
||
||     /* user_env is only specified for API version 1.2 and higher. */||
||     if (sudo_version < SUDO_API_MKVERSION(1, 2))||
||         user_env = NULL;||
||
||     if (fatal_setjmp() != 0) {||
||         /* called via fatal(), fatalx() or log_fatal() */||
||         fatal_disable_setjmp();||
||         debug_return_bool(-1);||
||     }||
||
||     debug_return_bool(sudo_auth_begin_session(pwd, user_env));||
||}|

|...||
||
||__dso_public struct policy_plugin sudoers_policy = {||
||     SUDO_POLICY_PLUGIN,||
||     SUDO_API_VERSION,||
||     sudoers_policy_open,||
||     sudoers_policy_close,||
||     sudoers_policy_version,||
||     sudoers_policy_check,||
||     sudoers_policy_list,||
||     sudoers_policy_validate,||
||     sudoers_policy_invalidate,||
||     sudoers_policy_init_session,  /*  (*init_session)||   */
||     sudoers_policy_register_hooks||
||};|



called by
(sudo/src/sudo.c)

|int||
||policy_init_session(struct command_details *details)||
||{||
||     int rval = true;||
||     debug_decl(policy_init_session, SUDO_DEBUG_PCOMM)||
||
||     if (policy_plugin.u.policy->init_session) {||
||         /*||
||          * Backwards compatibility for older API versions||
||          */||
||         switch (policy_plugin.u.generic->version) {||
||         case SUDO_API_MKVERSION(1, 0):||
||         case SUDO_API_MKVERSION(1, 1):||
||             rval = policy_plugin.u.policy_1_0->init_session(details->pw);||
||             break;||
||         default:||
||             rval = policy_plugin.u.policy->init_session(details->pw,||
||                 &details->envp);||
||         }||
||     }||
||     debug_return_bool(rval);||
||}||
||
||
|and finally
(sudo/src/exec.c)

|static int fork_cmnd(struct command_details *details, int sv[2])||
||{||
||	...||
||     ||if (policy_init_session(details) != true)||
||         fatalx(U_("policy plugin failed session initialization"));|||||/* exit(EXIT_FAILURE); OR siglongjmp(fatal_jmp, 1); ... but return is always true */|
||     ||
||     cmnd_pid = sudo_debug_fork();||
||     switch (cmnd_pid) {||
||     case -1:||
||         fatal(U_("unable to fork"));||
||         break;||
||     case 0:||
||         /* child */||
||         close(sv[0]);||
||         close(signal_pipe[0]);||
||         close(signal_pipe[1]);||
||         fcntl(sv[1], F_SETFD, FD_CLOEXEC);||
||         exec_cmnd(details, &cstat, sv[1]);||
||         send(sv[1], &cstat, sizeof(cstat), 0);||
||         sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 1);||
||         _exit(1);||
||     }||
||     sudo_debug_printf(SUDO_DEBUG_INFO, "executed %s, pid %d", details->command,||
||         (int)cmnd_pid);||
||     debug_return_int(cmnd_pid);||
||}||
|


I have not tried it with gdb yet...

To reproduce : (/etc/pam.d/sudo)
@include common-auth
@include common-account
session	required	pam_deny.so
@include common-session-noninteractive


If it's normal, why ? And how can I stop sudo to not run the command when/session/  return PAM_SESSION_ERR ?

Thanks and sorry for my bad english.


____________________________________________________________
sudo-workers mailing list <[email protected]>
For list information, options, or to unsubscribe, visit:
http://www.sudo.ws/mailman/listinfo/sudo-workers
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.