@@ -168,13 +168,14 @@ sudo_aix_valid_message(const char *message)
168168 debug_return_bool (true);
169169}
170170
171- /*
171+ /*
172172 * Change the user's password. If root changes the user's password
173173 * the ADMCHG flag is set on the account (and the user must change
174174 * it again) so we run passwd(1) as the user. This does mean that
175175 * the user will need to re-enter their original password again,
176176 * unlike with su(1). We may consider using pwdadm(1) as root to
177177 * change the password and then clear the flag in the future.
178+ * TODO: investigate using chpassx(3) instead.
178179 */
179180static bool
180181sudo_aix_change_password (const struct sudoers_context * ctx , const char * user )
@@ -187,9 +188,9 @@ sudo_aix_change_password(const struct sudoers_context *ctx, const char *user)
187188 debug_decl (sudo_aix_change_password , SUDOERS_DEBUG_AUTH );
188189
189190 /* Set SIGCHLD handler to default since we call waitpid() below. */
190- memset (& sa , 0 , sizeof (sa ));
191+ memset (& sa , 0 , sizeof (sa ));
191192 sigemptyset (& sa .sa_mask );
192- sa .sa_flags = SA_RESTART ;
193+ sa .sa_flags = SA_RESTART ;
193194 sa .sa_handler = SIG_DFL ;
194195 (void ) sigaction (SIGCHLD , & sa , & savechld );
195196
@@ -233,75 +234,69 @@ int
233234sudo_aix_verify (const struct sudoers_context * ctx , struct passwd * pw ,
234235 const char * prompt , sudo_auth * auth , struct sudo_conv_callback * callback )
235236{
236- char * pass , * message = NULL , * restrict_msg = NULL ;
237- int result = 1 , reenter = 0 , restrict_result = -1 , restrict_warn = 0 ;
238- int pwdexp_msg = 0 ;
237+ char * pass , * message = NULL ;
238+ int result , reenter = 0 ;
239239 int ret = AUTH_SUCCESS ;
240- void * login_state = NULL ;
240+ void * state = NULL ;
241241 debug_decl (sudo_aix_verify , SUDOERS_DEBUG_AUTH );
242242
243243 if (IS_NONINTERACTIVE (auth ))
244- debug_return_int (AUTH_NONINTERACTIVE );
245-
246- /* Use newer APIs to propogate the state information. */
247- restrict_result = loginrestrictionsx (pw -> pw_name , 0 , NULL ,
248- & restrict_msg , & login_state );
249- if (restrict_result != 0 )
250- {
251- if (restrict_msg != NULL && restrict_msg [0 ] != '\0' )
252- {
253- struct sudo_conv_message msg ;
254- struct sudo_conv_reply repl ;
255-
256- memset (& msg , 0 , sizeof (msg ));
257- msg .msg_type = SUDO_CONV_ERROR_MSG ;
258- msg .msg = restrict_msg ;
259- memset (& repl , 0 , sizeof (repl ));
260- sudo_conv (1 , & msg , & repl , NULL );
261- free (restrict_msg );
262- restrict_msg = NULL ;
263- restrict_warn = 1 ;
264- }
265- if (!restrict_warn )
266- sudo_warn ("loginrestrictionsx" );
267- debug_return_int (AUTH_ERROR );
244+ debug_return_int (AUTH_NONINTERACTIVE );
245+
246+ /* Use newer APIs to propagate the state information. */
247+ result = loginrestrictionsx (pw -> pw_name , 0 , NULL , & message , & state );
248+ if (result != 0 ) {
249+ if (message != NULL && message [0 ] != '\0' ) {
250+ sudo_printf (SUDO_CONV_ERROR_MSG |SUDO_CONV_PREFER_TTY ,
251+ "%s" , message );
252+ } else {
253+ sudo_warn ("loginrestrictionsx" );
254+ }
255+ free (message );
256+ free (state );
257+ debug_return_int (AUTH_ERROR );
268258 }
269259
270260 do {
271261 pass = auth_getpass (prompt , SUDO_CONV_PROMPT_ECHO_OFF , callback );
272- if (pass == NULL )
262+ if (pass == NULL ) {
263+ result = -1 ;
273264 break ;
265+ }
274266 free (message );
275267 message = NULL ;
276- result = authenticatex (pw -> pw_name , pass , & reenter , & message , & login_state );
268+ result = authenticatex (pw -> pw_name , pass , & reenter , & message , & state );
277269 freezero (pass , strlen (pass ));
278270 prompt = message ;
279271 } while (reenter );
280272
281273 if (result != 0 ) {
282- /* Display error message, if any. */
283- if (sudo_aix_valid_message (message ))
284- sudo_printf (SUDO_CONV_ERROR_MSG |SUDO_CONV_PREFER_TTY ,
285- "%s" , message );
286- ret = pass ? AUTH_FAILURE : AUTH_INTR ;
274+ if (pass == NULL ) {
275+ /* User interrupted password prompt with ^C. */
276+ ret = AUTH_INTR ;
277+ } else {
278+ /* Display error message, if any. */
279+ if (sudo_aix_valid_message (message )) {
280+ sudo_printf (SUDO_CONV_ERROR_MSG |SUDO_CONV_PREFER_TTY ,
281+ "%s" , message );
282+ }
283+ ret = AUTH_FAILURE ;
284+ }
287285 }
288- free (message );
289- message = NULL ;
290286
291287 /* Check if password expired and allow user to change it if possible. */
292288 if (ret == AUTH_SUCCESS ) {
293- result = passwdexpiredx (pw -> pw_name , & message , & login_state );
289+ free (message );
290+ message = NULL ;
291+ result = passwdexpiredx (pw -> pw_name , & message , & state );
294292 if (message != NULL && message [0 ] != '\0' ) {
295- pwdexp_msg = 1 ;
296293 int msg_type = SUDO_CONV_PREFER_TTY ;
297294 msg_type |= result ? SUDO_CONV_ERROR_MSG : SUDO_CONV_INFO_MSG ,
298295 sudo_printf (msg_type , "%s" , message );
299- free (message );
300- message = NULL ;
301296 }
302297 switch (result ) {
303298 case 0 :
304- /* password not expired. */
299+ /* password not expired */
305300 break ;
306301 case 1 :
307302 /* password expired, user must change it */
@@ -311,10 +306,12 @@ sudo_aix_verify(const struct sudoers_context *ctx, struct passwd *pw,
311306 }
312307 break ;
313308 case 2 :
314- case 3 :
315- /* password expired, only admin can change it */
316- if (!pwdexp_msg )
317- sudo_printf (SUDO_CONV_ERROR_MSG , "Your password expired, only admin can change it.\n" );
309+ case 3 :
310+ /* password expired, cannot be updated by user */
311+ if (message == NULL ) {
312+ sudo_warnx (
313+ U_ ("Password expired, contact your system administrator" ));
314+ }
318315 ret = AUTH_ERROR ;
319316 break ;
320317 default :
@@ -324,6 +321,8 @@ sudo_aix_verify(const struct sudoers_context *ctx, struct passwd *pw,
324321 break ;
325322 }
326323 }
324+ free (message );
325+ free (state );
327326
328327 debug_return_int (ret );
329328}
0 commit comments