How to check password in Linux by using C or shell?
Asked Answered
D

3

4

I have a program written in C running on a embedded Linux, sometimes it want to check the password of a system user.

  1. If I can get the crypt salt of /etc/passwd, I can use crypt() to check the correction of user password.
  2. Is there any script of shell can help me check the password? Such as check_passwd username password, then it return a value for correct or incorrect? Thanks!
Downwash answered 6/7, 2013 at 2:42 Comment(5)
Have a look at the source code of the login program.Manta
Also have a look at pam - pluggable authentication modulesManta
Thank you for answering! I found that the code in libbb/correct_password.c of busybox helps a lot for the solution. Still thanks~Downwash
Glad you found a solution. Generally you don't want to do this though - a user should really not provide their password to anything but login or sudo.Teeterboard
I also think so. This program is to login system from web, because some problem in previous design, we put the password in /etc/passwd and lead to this question. Now I move all the password to database, so it's OK.Downwash
O
3

I had been solving the same task recently. Here is an example of C function (link with -lcrypt). Note that you need to have read permissions for files /etc/passwd and /etc/shadow.

#include <sys/types.h>
#include <pwd.h>
#include <shadow.h>
#include <crypt.h>
#include <string.h>
#include <stdio.h>

/// @return 0 - password is correct, otherwise no
int CheckPassword( const char* user, const char* password )
{
    struct passwd* passwdEntry = getpwnam( user );
    if ( !passwdEntry )
    {
        printf( "User '%s' doesn't exist\n", user );
        return 1;
    }

    if ( 0 != strcmp( passwdEntry->pw_passwd, "x" ) )
    {
        return strcmp( passwdEntry->pw_passwd, crypt( password, passwdEntry->pw_passwd ) );
    }
    else
    {
        // password is in shadow file
        struct spwd* shadowEntry = getspnam( user );
        if ( !shadowEntry )
        {
            printf( "Failed to read shadow entry for user '%s'\n", user );
            return 1;
        }

        return strcmp( shadowEntry->sp_pwdp, crypt( password, shadowEntry->sp_pwdp ) );
    }
}
Orelu answered 30/7, 2020 at 12:21 Comment(1)
Checking for user won't work if name service switch uses different sources. And just checking for 'x' in field 'password' does not handle empty string or an asterisk. This function is very "incompatible". Better use system libs (PAM).Raffaello
F
1

As suggested above, the correct way to handle this is to use pluggable authentication modules. You have to add libpam to whatever embedded linux you're using, but this is generally easy enough (buildroot provides a linux-pam package, for example).

Fecit answered 5/9, 2013 at 17:23 Comment(1)
Yes. And PAM also handles the password field correctly if there is not an "x".Raffaello
A
0

See Given a linux username and a password how can I test if it is a valid account? for how to go about checking if a password given by a user is valid for that user.

Aversion answered 6/9, 2013 at 1:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.