0

I'm currently making a FTP server and I would like to implement real authentication. I mean I have users on my system and I would like them to be able to log in my FTP server with a client (like Filezilla for instance) using their username password saved in the system.

But I don't know the steps to follow to implement this and to give good rights (impossible to delete files the user is not the owner, etc...).

I know I have to find the login/home directory in the /etc/passwd file and I know I can find the hashed password in the /etc/shadow file, but how are those passwords encrypted?

Once logged in, do I have to check if the user has the rights to delete/access/write files myself or is there a way to let the system know?

Thanks.

Julien Fouilhé
  • 2,583
  • 3
  • 30
  • 56
  • You don't have to check permissions yourself, instead the file functions will return with an error if they can't open, read or write files. You should check `errno` in that case, if it's `EACCESS` then it means access is denied. – Some programmer dude Apr 11 '13 at 10:02
  • 1
    Did you consider forking the server to run as the user logging in? – Adrian Panasiuk Apr 11 '13 at 10:02
  • @AdrianPanasiuk I'm already forking, but I wonder exactly how to do this. – Julien Fouilhé Apr 11 '13 at 10:04
  • To set the password of an user, type `passwd user` and set it. It will be encrypted in `/etc/passwd` or `/etc/shadow` (depending on configuration) and you do not have to mind about it any more. – fedorqui Apr 11 '13 at 10:04
  • @fedorqui My problem is not to **find** the password, my problem is how to login as an **already existant** user in C once I checked both login/password are valid so my FTP server (launched as root to be able to access protected files) is secured and so the user can not do what he wants and access only his own files. – Julien Fouilhé Apr 11 '13 at 10:06
  • Apparently it's not that easy as I thought: http://stackoverflow.com/questions/13040644/setuid-equivalent-for-non-root-users – Adrian Panasiuk Apr 11 '13 at 10:10
  • You can check the rights yourself. You can also let the OS do the checking for you. Just ask yourself who is going to be better at it. – n. m. could be an AI Apr 11 '13 at 10:12
  • @AdrianPanasiuk Ok, so if I use `setuid()` in my program fork, it will be like if the process has been launched by the user himself? Thanks again. – Julien Fouilhé Apr 11 '13 at 10:15
  • 1
    For checking the password, see `man 3 crypt`. You have to take the salt from `/etc/passwd` (including any `$$$`), then encrypt the password with the salt, and compare the result with the encrypted password. If they match, you are good to go. – n. m. could be an AI Apr 11 '13 at 10:19
  • 1
    From setfsuid man page, relevant for setuid who changes the effective uid: `The system call setfsuid() sets the user ID that the Linux kernel uses to check for all accesses to the file system. Normally, the value of fsuid will shadow the value of the effective user ID. In fact, whenever the effective user ID is changed, fsuid will also be changed to the new value of the effective user ID. ` – Adrian Panasiuk Apr 11 '13 at 10:21
  • @n.m. So the salt for the password is the second field of each line, so x in Ubuntu, thanks. – Julien Fouilhé Apr 11 '13 at 10:37
  • @AdrianPanasiuk That's exactly the kind of function I was looking for, thank you. – Julien Fouilhé Apr 11 '13 at 10:37
  • But use `setuid`! It doesn't limit itself to fsuid, it changes other important uids too. – Adrian Panasiuk Apr 11 '13 at 10:39
  • No x is not the salt. It means the encrypted password, including the salt, is not here but in /etc/shadow. You need to use routines from `shadow(3)` to access it. – n. m. could be an AI Apr 11 '13 at 10:49

3 Answers3

4

You shouldn't expect the password to be stored in a particular file and neither assume it will be crypted (hashed actually) a specific way.

Passwords might be provided by a centralized database like NIS or might even be stored in a way the Unix system you are running in is unable to process, like when authentication is delegated to an LDAP or active directory.

A proper way is to use the pam framework which was precisely designed to provide a single interface hiding the underlying complex/flexible settings.

Have a look at the getpwuid, pam_start and pam_authenticate manual pages for your Unix implementation.

jlliagre
  • 29,783
  • 6
  • 61
  • 72
1

This depends on OS you are using. For FreeBSD it is Crypt algorithm with changing underlying hash (SHA-512 by default), see http://www.freebsd.org/doc/en/books/handbook/crypt.html. Other OSes can use Bcrypt or others.

Nickolay Olshevsky
  • 13,706
  • 1
  • 34
  • 48
0

This looks relevant:

Name

pam_unix - Module for traditional password authentication

Synopsis

pam_unix.so [...]

Description

This is the standard Unix authentication module. It uses standard calls from the system's libraries to retrieve and set account information as well as authentication. Usually this is obtained from the /etc/passwd and the /etc/shadow file as well if shadow is enabled.

The action of authentizing against the host's unix accounts sounds like something a lot of programs might want to do, so it makes sense to use a library for the task instead of rolling your own.

Community
  • 1
  • 1
Adrian Panasiuk
  • 7,249
  • 5
  • 33
  • 54