Skip to content

Latest commit

 

History

History
100 lines (80 loc) · 5.1 KB

authenticating.md

File metadata and controls

100 lines (80 loc) · 5.1 KB

ProFTPD Developer Guide: Internal: Authenticating Users


Table of Contents


Authenticating Users

When an FTP client connects to ProFTPD, the client needs to authenticate itself, as per the FTP protocol. The client sends a USER command followed by a PASS command in most cases.

Upon receiving a USER command, ProFTPD will first check to see if the requested user is allowed to log in, based on any <Limit LOGIN> sections. Then it will check to see if the login is allowed by any configured MaxClients, MaxClientsPerHost, and MaxHostsPerUser directives.

When ProFTPD receives a PASS command, it will again check for configured MaxClients, MaxClientsPerHost, and MaxHostsPerUser limits. The first check, during the handling of the USER command, handles UserAliased user names; this subsequent check handles real user names. The actual work of authenticating the user then takes place (more on this below). If the authentication succeeds, any DisplayLogin or AccessGrantMsg messages are sent to the client. Otherwise, any AccessDenyMsg message is sent.

During authentication, the process handling the connection is running under the identity configured using the User and Group configuration directives. Only after successfully authenticating the user will the process assume the identity and privileges of that authenticated user. This process of authentication is handled by the setup_env() function of the mod_auth module, and is quite involved.

First, this function determines whether the login request is for an <Anonymous> server, or for a real user. Unknown users are rejected at this point. The determination of a "known" user is done via the pr_auth_getpwnam() Auth API. Modules that wish to supply their own authentication routines will need to provide authentication handlers. The Auth API "cascades" through each of the registered authentication modules of the server, asking each module in turn to authenticate the user until an error is encountered, or until a module successfully returns the requested information. This design allows multiple authentication schemes to be present simultaneously.

The pr_auth_getgroups() Auth API function is similarly used to request the supplemental group membership information, both group names and group IDs, from authentication modules. The list of obtained group IDs, if any, will subsequently be passed on to the setgroups(2) system call. At this point, I would like to point out a common error message pertaining to supplemental group membership:

  "unable to set groups: Invalid argument"

This message will occur for one of two reasons: negative IDs for the user, or the user is a member of more than the maximum allowable number of groups; see documentation on the _SC_NGROUPS_MAX variable of the sysconf(3) library call.

Next, the function will check to see if the requested user is "root"; logging in as "root" requires that the RootLogin directive be explicitly set; in general, allowing remote root login a Very Bad Idea.

At this point, the given password is checked. If any UserPassword directives are set, then the configured password will be checked using the pr_auth_check() Auth API function. Otherwise, the pr_auth_authenticate() Auth API is called.

If the requested user has succeeded up to this point, the default directory in which to place the user, either their home directory or any applicable DefaultChdir directives, is retrieved. This path is checked for any applicable <Limit> directives. Next, after logging a wtmp or utmp log entry, this function will check and apply any DefaultRoot configuration directives as needed. Last, the identity of the current process is changed to be that of the authenticated user.

At this point, unless authentication has failed at any point earlier, the authentication process is done. Any .ftpaccess files are parsed, the default transfer mode is set (configurable via DefaultTransferMode), and the scoreboard is updated.

Authentication is a complex process, and may fail at several points: if an authentication module encounters an error while authenticating, if the login is not for a valid user or is not a valid UserAlias, if the login is denied by an applicable <Limit LOGIN>, if the password given was incorrect or expired, if the account used is disabled, if the user's account includes an invalid shell, if the login name is listed in the /etc/ftpusers file and the server is configured to honour that file, etc.


Table of Contents