C++ - Problem in asking and checking user's passwd

This is the source code:

#include <pwd.h>
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
    struct passwd *user;
    char login[200]="alex", password[200]="qwertyuiop";

       if ((user= getpwnam(login)) == NULL)
            cout << "No such user\n";
       else if (!strcmp(user->pw_passwd, crypt(password, user->pw_passwd)))
            cout << "Password correct\n";
       else
            cout << "Password incorrect\n";
    return 0;
}

but I got error about crypt..Why is that?

Hi.

What error are you getting? I can compile the code no problem.

I'm not sure that you can do what you are trying to do.

From the crypt man page:

The crypt() function performs password encryption, based on the NBS Data Encryption Standard (DES).
Additional code has been added to deter key search attempts

user->pw_passwd is completely obfuscated and can't be compared to a crypted version of the string password.

2 errors:

1./home/alex/Qt/libtest/main.cpp:12: undefined reference to `crypt'
2.:-1: error: collect2: ld returned 1 exit status

Try including unistd.h or crypt.h

If you look at the man page for crypt, it should tell you where it is.

Hmmm, the undefined reference to `crypt' is just a notice, the real error is that
:-1: error: collect2: ld returned 1 exit status

I would say that the first line is the real error (the linker can't link something that doesn't exist).

So, what do you suggest me for this?

To get your code to compile, I would suggest you include a header that contains the definition of the crypt function that you are using.

To get your code to work, I would suggest is futile.

The function seems designed to prevent such brute force attacks. The man page clearly explained that.

Wtf???? You can have a knife to kill or to cut your bread!!!
There is no protection if you want to kill somebody!!!
What can I do know????? :frowning: :frowning:

Passwords need this protection becase otherwise people would do things like what you're doing.

What is the ultimate goal here?

I am making a program in which you can set a password on program launch. But in order to set it you have to type user login and passwd. By this way your little brother will not set a passwd !!!

  1. Link with "-lcrypt". Then your code will compile. It still won't work, though.

  2. The pw_passwd field isn't obfuscated as much as it's not even used any more. See 'man getspnam".

---------- Post updated at 09:37 AM ---------- Previous update was at 09:34 AM ----------

That's pointless.

Just set the permissions on the binary to only allow execution by the owner.

Sometimes there are persons that you allow them to log-in from your account, aren't they?

So, to conclude, there is NO way to check user login and password from C++. Is this right???

No, never. This is a very poor practice, when UNIX has such a wide arrays of better ways to share and restrict things.

Better to use existing systems rather than try and craft your own; probably safer too, less likely to break when the security system changes a little and less prone to bugs of a very dangerous sort. PAM, the usual Linux authentication system, might be one way. sudo would be another, since it can be configured to ask you for your own password when you try to run 'sudo something'.

I was thinking to use gksudo. Is there anyway to see if these commands were successfully accomplished?
E.g.
gksudo -i > alex
And then if password confirmation will be successful, "1" or "successful" will be writen to file "alex"
Is this or something similar possible?

A few things...
1) You haven't given sudo anything to do, so I don't think that will work. If you want to change the password, why not sudo -u username passwd username? That will request the user's login and, only if successful, prompt him to change the password.

2) I don't think you really want to capture the output here, do you? You want the user to see it and interact with it. Using gksudo instead of sudo in a terminal means you don't get all this nice prewritten tested-to-death software to use(no google hits for gkpasswd). Why not use it?

3) Check the program's return status, not it's output. If you're unsure what an exit status is, try this from shell:

$ true ; echo $?
0
$ false ; echo $?
1
$ true && echo 'This succeeded'
This succeeded
$ false && echo 'This succeeded'
$ true || echo 'This failed'
$ false || echo 'This failed'
This failed
$

And the following program should do this:

int main(void)
{
       return(42);
}
$ ./return42 ; echo $?
42
$

Traditionally programs return 0 on success, nonzero on failure. Just check if it returned zero and you'll know if it succeeded.

Ok thx for the help. I knew that every program returns a value. How do I exactly check the returned value?

Depends how exactly you ran it. How are you running it?

I am thinking of using the system function at stdlib.h calling gksudo. Then writing a value to a file or something and then, through C++ check this value and decide if the access is accepted or not...

From man system:

RETURN VALUE
       The value returned is -1 on  error  (e.g.   fork(2)  failed),  and  the
       return  status  of the command otherwise.  This latter return status is
       in the format specified in wait(2).  Thus, the exit code of the command
       will  be  WEXITSTATUS(status).   In case /bin/sh could not be executed,
       the exit status will be that of a command that does exit(127).

       If the value of command is NULL, system() returns non-zero if the shell
       is available, and zero if not.

To use WEXITSTATUS you should also

#include <sys/types.h>
#include <sys/wait.h>