summaryrefslogtreecommitdiff
path: root/loginutils
diff options
context:
space:
mode:
Diffstat (limited to 'loginutils')
-rw-r--r--loginutils/login.c65
1 files changed, 42 insertions, 23 deletions
diff --git a/loginutils/login.c b/loginutils/login.c
index bddc0f533..53d3e528b 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -239,9 +239,14 @@ int login_main(int argc, char **argv)
239 char full_tty[TTYNAME_SIZE]; 239 char full_tty[TTYNAME_SIZE];
240 USE_SELINUX(security_context_t user_sid = NULL;) 240 USE_SELINUX(security_context_t user_sid = NULL;)
241 USE_FEATURE_UTMP(struct utmp utent;) 241 USE_FEATURE_UTMP(struct utmp utent;)
242 USE_PAM(pam_handle_t *pamh;) 242#if ENABLE_PAM
243 USE_PAM(int pamret;) 243 int pamret;
244 USE_PAM(const char *failed_msg;) 244 pam_handle_t *pamh;
245 const char *pamuser;
246 const char *failed_msg;
247 struct passwd pwdstruct;
248 char pwdbuf[256];
249#endif
245 250
246 short_tty = full_tty; 251 short_tty = full_tty;
247 username[0] = '\0'; 252 username[0] = '\0';
@@ -297,18 +302,18 @@ int login_main(int argc, char **argv)
297#if ENABLE_PAM 302#if ENABLE_PAM
298 pamret = pam_start("login", username, &conv, &pamh); 303 pamret = pam_start("login", username, &conv, &pamh);
299 if (pamret != PAM_SUCCESS) { 304 if (pamret != PAM_SUCCESS) {
300 failed_msg = "pam_start"; 305 failed_msg = "start";
301 goto pam_auth_failed; 306 goto pam_auth_failed;
302 } 307 }
303 /* set TTY (so things like securetty work) */ 308 /* set TTY (so things like securetty work) */
304 pamret = pam_set_item(pamh, PAM_TTY, short_tty); 309 pamret = pam_set_item(pamh, PAM_TTY, short_tty);
305 if (pamret != PAM_SUCCESS) { 310 if (pamret != PAM_SUCCESS) {
306 failed_msg = "pam_set_item(TTY)"; 311 failed_msg = "set_item(TTY)";
307 goto pam_auth_failed; 312 goto pam_auth_failed;
308 } 313 }
309 pamret = pam_authenticate(pamh, 0); 314 pamret = pam_authenticate(pamh, 0);
310 if (pamret != PAM_SUCCESS) { 315 if (pamret != PAM_SUCCESS) {
311 failed_msg = "pam_authenticate"; 316 failed_msg = "authenticate";
312 goto pam_auth_failed; 317 goto pam_auth_failed;
313 /* TODO: or just "goto auth_failed" 318 /* TODO: or just "goto auth_failed"
314 * since user seems to enter wrong password 319 * since user seems to enter wrong password
@@ -318,28 +323,42 @@ int login_main(int argc, char **argv)
318 /* check that the account is healthy */ 323 /* check that the account is healthy */
319 pamret = pam_acct_mgmt(pamh, 0); 324 pamret = pam_acct_mgmt(pamh, 0);
320 if (pamret != PAM_SUCCESS) { 325 if (pamret != PAM_SUCCESS) {
321 failed_msg = "account setup"; 326 failed_msg = "acct_mgmt";
322 goto pam_auth_failed; 327 goto pam_auth_failed;
323 } 328 }
324 /* read user back */ 329 /* read user back */
325 { 330 pamuser = NULL;
326 const char *pamuser; 331 /* gcc: "dereferencing type-punned pointer breaks aliasing rules..."
327 /* gcc: "dereferencing type-punned pointer breaks aliasing rules..." 332 * thus we cast to (void*) */
328 * thus we cast to (void*) */ 333 if (pam_get_item(pamh, PAM_USER, (void*)&pamuser) != PAM_SUCCESS) {
329 if (pam_get_item(pamh, PAM_USER, (void*)&pamuser) != PAM_SUCCESS) { 334 failed_msg = "get_item(USER)";
330 failed_msg = "pam_get_item(USER)"; 335 goto pam_auth_failed;
331 goto pam_auth_failed;
332 }
333 safe_strncpy(username, pamuser, sizeof(username));
334 } 336 }
335 /* If we get here, the user was authenticated, and is 337 if (!pamuser || !pamuser[0])
336 * granted access. */ 338 goto auth_failed;
337 pw = getpwnam(username); 339 safe_strncpy(username, pamuser, sizeof(username));
338 if (pw) 340 /* Don't use "pw = getpwnam(username);",
339 break; 341 * PAM is said to be capable of destroying static storage
340 goto auth_failed; 342 * used by getpwnam(). We are using safe(r) function */
343 pw = NULL;
344 getpwnam_r(username, &pwdstruct, pwdbuf, sizeof(pwdbuf), &pw);
345 if (!pw)
346 goto auth_failed;
347 pamret = pam_open_session(pamh, 0);
348 if (pamret != PAM_SUCCESS) {
349 failed_msg = "open_session";
350 goto pam_auth_failed;
351 }
352 pamret = pam_setcred(pamh, PAM_ESTABLISH_CRED);
353 if (pamret != PAM_SUCCESS) {
354 failed_msg = "setcred";
355 goto pam_auth_failed;
356 }
357 break; /* success, continue login process */
358
341 pam_auth_failed: 359 pam_auth_failed:
342 bb_error_msg("%s failed: %s (%d)", failed_msg, pam_strerror(pamh, pamret), pamret); 360 bb_error_msg("pam_%s call failed: %s (%d)", failed_msg,
361 pam_strerror(pamh, pamret), pamret);
343 safe_strncpy(username, "UNKNOWN", sizeof(username)); 362 safe_strncpy(username, "UNKNOWN", sizeof(username));
344#else /* not PAM */ 363#else /* not PAM */
345 pw = getpwnam(username); 364 pw = getpwnam(username);