dyanamically creating directories with pam_mkhomedir and mysql for vsftpd
Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
I've installed vsftpd using the following instructions
http://www.camcloud.com/blog/setup-vsftpd-with-virtual-users-using-mysql
I'm trying to automatically/dynamically create directories for each user as they log into the ftp server.
I have the following /etc/pam.d/vsftpd
which does not automatically create the directory.
Static Directory Configuration Code
session optional pam_keyinit.so force revoke
auth required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
account required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
My question is how to properly use pam_mkhomedir to create the directory with the username from mysql. I found this documentation https://www.dalemacartney.com/2012/07/30/auto-creation-of-user-home-directories-in-linux/
I'm wondering if this is the proper configuration, I'd also like to know how he username is set for the directory. I do not see anywhere's in the code where username is applied, or is that something that just happens behind the scenes?
Dynamic Directory Configuration Code
session optional pam_keyinit.so force revoke
auth required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
account required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
linux pam vsftpd
add a comment |Â
up vote
2
down vote
favorite
I've installed vsftpd using the following instructions
http://www.camcloud.com/blog/setup-vsftpd-with-virtual-users-using-mysql
I'm trying to automatically/dynamically create directories for each user as they log into the ftp server.
I have the following /etc/pam.d/vsftpd
which does not automatically create the directory.
Static Directory Configuration Code
session optional pam_keyinit.so force revoke
auth required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
account required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
My question is how to properly use pam_mkhomedir to create the directory with the username from mysql. I found this documentation https://www.dalemacartney.com/2012/07/30/auto-creation-of-user-home-directories-in-linux/
I'm wondering if this is the proper configuration, I'd also like to know how he username is set for the directory. I do not see anywhere's in the code where username is applied, or is that something that just happens behind the scenes?
Dynamic Directory Configuration Code
session optional pam_keyinit.so force revoke
auth required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
account required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
linux pam vsftpd
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I've installed vsftpd using the following instructions
http://www.camcloud.com/blog/setup-vsftpd-with-virtual-users-using-mysql
I'm trying to automatically/dynamically create directories for each user as they log into the ftp server.
I have the following /etc/pam.d/vsftpd
which does not automatically create the directory.
Static Directory Configuration Code
session optional pam_keyinit.so force revoke
auth required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
account required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
My question is how to properly use pam_mkhomedir to create the directory with the username from mysql. I found this documentation https://www.dalemacartney.com/2012/07/30/auto-creation-of-user-home-directories-in-linux/
I'm wondering if this is the proper configuration, I'd also like to know how he username is set for the directory. I do not see anywhere's in the code where username is applied, or is that something that just happens behind the scenes?
Dynamic Directory Configuration Code
session optional pam_keyinit.so force revoke
auth required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
account required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
linux pam vsftpd
I've installed vsftpd using the following instructions
http://www.camcloud.com/blog/setup-vsftpd-with-virtual-users-using-mysql
I'm trying to automatically/dynamically create directories for each user as they log into the ftp server.
I have the following /etc/pam.d/vsftpd
which does not automatically create the directory.
Static Directory Configuration Code
session optional pam_keyinit.so force revoke
auth required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
account required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
My question is how to properly use pam_mkhomedir to create the directory with the username from mysql. I found this documentation https://www.dalemacartney.com/2012/07/30/auto-creation-of-user-home-directories-in-linux/
I'm wondering if this is the proper configuration, I'd also like to know how he username is set for the directory. I do not see anywhere's in the code where username is applied, or is that something that just happens behind the scenes?
Dynamic Directory Configuration Code
session optional pam_keyinit.so force revoke
auth required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
account required pam_mysql.so verbose=1 user=mydbusername passwd=mydbpass host=localhost db=mydb table=mydb_table usercolumn=username passwdcolumn=password crypt=0
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
linux pam vsftpd
linux pam vsftpd
edited 45 secs ago
Rui F Ribeiro
37.3k1374118
37.3k1374118
asked Jan 29 '15 at 20:03
Code Junkie
1237
1237
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
2
down vote
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
As you can see, pam_mkhomedir.so
acts at the session level. This means that it acts after the user has been authenticated (by the auth
facility). To do so, it defines the following PAM-specific function :
PAM_EXTERN
int pam_sm_open_session(pam_handle_t * pamh, int flags,
int argc, const char **argv);
As I said, this function is called when the user has been authenticated. Therefore, when it retrieves the PAM user handle...
/* Determine the user name so we can get the home directory */
retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
... it gets access to the name of an authenticated, existing user. With this information, the module will be able to retrieve what it needs (the path to a home directory) through a simple getpwnam(3)
library call:
/* Get the password entry */
pwd = getpwnam(user);
This will return the following structure, filled with information about the user:
struct passwd
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
;
Now, if you wonder where this information is coming from, have a look at /etc/nsswitch.conf
. The Name Service Switch (NSS) is here to provide information regarding names in general (which can be usernames, aliases, groups, hosts, ... see nsswitch.conf(5)
for more details). If the guide you followed is complete enough, it should have had you configure both PAM and NSS: the first handles authentication and account/session management, while the other is merely here to provide name information. In other words, the first one can perform read/write operations, while the second one is read-only.
Once pam_mkhomedir.so
has retrieved the path to the user's home directory, all it has to do is check whether or not it exists, and create it if it does not:
/* Stat the home directory, if something exists then we
* assume it is correct and return a success. */
if(stat(pwd->pw_dir, &st) == 0) return PAM_SUCCESS;
return create_homedir(..., pwd, ...);
The create_homedir
function is defined by the module itself, and it is a bit too long for me to paste it here. Just see it as a big mkdir(2)
call, which handles specific cases and makes sure everything goes smoothly. If you're interested in more details, have a look at pam_mkhomedir.so
's source code. I used this version of it for my answer (it was written by Jason Gunthorpe, whose name is also on my pam_mkhomedir.so
manpage).
Now, as far as I'm concerned, I think the guide you followed is a little incomplete, or at least, the MySQL table it has you create is:
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | UNI | NULL | |
| pass | varchar(50) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
This table is probably detailed enough for VSFTPd to work. Since it is configured with a home root, it can easily determine a user's home directory: $ftp_root/username
. This is actually set with the local_root
parameter:
local_root=/home/vsftpd/$USER
However, pam_mkhomedir.so
is not VSFTPd. It doesn't use this mechanism, but relies on NSS (through getpwnam(3)
). The problem is: your MySQL table does not provide enough information for NSS to fill the struct passwd
we saw earlier. In order to have NSS use MySQL as a source, you'll need to install nss-mysql, which requires a larger MySQL table. This will require adjustments in your VSFTPd configuration, but you should have no problem in having VSFTPd and nss-mysql cohabitate.
This directory gives an example for a minimal nss-mysql setup. The MySQL table for users is defined as follows:
+-----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | | NULL | |
| username_canonical | varchar(255) | NO | UNI | NULL | |
| email | varchar(255) | NO | | NULL | |
| email_canonical | varchar(255) | NO | UNI | NULL | |
| enabled | tinyint(1) | NO | | NULL | |
| salt | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
| last_login | datetime | YES | | NULL | |
| locked | tinyint(1) | NO | | NULL | |
| expired | tinyint(1) | NO | | NULL | |
| expires_at | datetime | YES | | NULL | |
| confirmation_token | varchar(255) | YES | | NULL | |
| password_requested_at | datetime | YES | | NULL | |
| roles | longtext | NO | | NULL | |
| credentials_expired | tinyint(1) | NO | | NULL | |
| credentials_expire_at | datetime | YES | | NULL | |
+-----------------------+--------------+------+-----+---------+----------------+
Now, you might not need all these fields yourself, but keep in mind that struct passwd
structure we saw earlier, and make sure nss-mysql has enough data to fill it :) Besides, the nss-mysql configuration files are flexible enough for you to use default values for anything.
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
As you can see, pam_mkhomedir.so
acts at the session level. This means that it acts after the user has been authenticated (by the auth
facility). To do so, it defines the following PAM-specific function :
PAM_EXTERN
int pam_sm_open_session(pam_handle_t * pamh, int flags,
int argc, const char **argv);
As I said, this function is called when the user has been authenticated. Therefore, when it retrieves the PAM user handle...
/* Determine the user name so we can get the home directory */
retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
... it gets access to the name of an authenticated, existing user. With this information, the module will be able to retrieve what it needs (the path to a home directory) through a simple getpwnam(3)
library call:
/* Get the password entry */
pwd = getpwnam(user);
This will return the following structure, filled with information about the user:
struct passwd
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
;
Now, if you wonder where this information is coming from, have a look at /etc/nsswitch.conf
. The Name Service Switch (NSS) is here to provide information regarding names in general (which can be usernames, aliases, groups, hosts, ... see nsswitch.conf(5)
for more details). If the guide you followed is complete enough, it should have had you configure both PAM and NSS: the first handles authentication and account/session management, while the other is merely here to provide name information. In other words, the first one can perform read/write operations, while the second one is read-only.
Once pam_mkhomedir.so
has retrieved the path to the user's home directory, all it has to do is check whether or not it exists, and create it if it does not:
/* Stat the home directory, if something exists then we
* assume it is correct and return a success. */
if(stat(pwd->pw_dir, &st) == 0) return PAM_SUCCESS;
return create_homedir(..., pwd, ...);
The create_homedir
function is defined by the module itself, and it is a bit too long for me to paste it here. Just see it as a big mkdir(2)
call, which handles specific cases and makes sure everything goes smoothly. If you're interested in more details, have a look at pam_mkhomedir.so
's source code. I used this version of it for my answer (it was written by Jason Gunthorpe, whose name is also on my pam_mkhomedir.so
manpage).
Now, as far as I'm concerned, I think the guide you followed is a little incomplete, or at least, the MySQL table it has you create is:
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | UNI | NULL | |
| pass | varchar(50) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
This table is probably detailed enough for VSFTPd to work. Since it is configured with a home root, it can easily determine a user's home directory: $ftp_root/username
. This is actually set with the local_root
parameter:
local_root=/home/vsftpd/$USER
However, pam_mkhomedir.so
is not VSFTPd. It doesn't use this mechanism, but relies on NSS (through getpwnam(3)
). The problem is: your MySQL table does not provide enough information for NSS to fill the struct passwd
we saw earlier. In order to have NSS use MySQL as a source, you'll need to install nss-mysql, which requires a larger MySQL table. This will require adjustments in your VSFTPd configuration, but you should have no problem in having VSFTPd and nss-mysql cohabitate.
This directory gives an example for a minimal nss-mysql setup. The MySQL table for users is defined as follows:
+-----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | | NULL | |
| username_canonical | varchar(255) | NO | UNI | NULL | |
| email | varchar(255) | NO | | NULL | |
| email_canonical | varchar(255) | NO | UNI | NULL | |
| enabled | tinyint(1) | NO | | NULL | |
| salt | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
| last_login | datetime | YES | | NULL | |
| locked | tinyint(1) | NO | | NULL | |
| expired | tinyint(1) | NO | | NULL | |
| expires_at | datetime | YES | | NULL | |
| confirmation_token | varchar(255) | YES | | NULL | |
| password_requested_at | datetime | YES | | NULL | |
| roles | longtext | NO | | NULL | |
| credentials_expired | tinyint(1) | NO | | NULL | |
| credentials_expire_at | datetime | YES | | NULL | |
+-----------------------+--------------+------+-----+---------+----------------+
Now, you might not need all these fields yourself, but keep in mind that struct passwd
structure we saw earlier, and make sure nss-mysql has enough data to fill it :) Besides, the nss-mysql configuration files are flexible enough for you to use default values for anything.
add a comment |Â
up vote
2
down vote
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
As you can see, pam_mkhomedir.so
acts at the session level. This means that it acts after the user has been authenticated (by the auth
facility). To do so, it defines the following PAM-specific function :
PAM_EXTERN
int pam_sm_open_session(pam_handle_t * pamh, int flags,
int argc, const char **argv);
As I said, this function is called when the user has been authenticated. Therefore, when it retrieves the PAM user handle...
/* Determine the user name so we can get the home directory */
retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
... it gets access to the name of an authenticated, existing user. With this information, the module will be able to retrieve what it needs (the path to a home directory) through a simple getpwnam(3)
library call:
/* Get the password entry */
pwd = getpwnam(user);
This will return the following structure, filled with information about the user:
struct passwd
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
;
Now, if you wonder where this information is coming from, have a look at /etc/nsswitch.conf
. The Name Service Switch (NSS) is here to provide information regarding names in general (which can be usernames, aliases, groups, hosts, ... see nsswitch.conf(5)
for more details). If the guide you followed is complete enough, it should have had you configure both PAM and NSS: the first handles authentication and account/session management, while the other is merely here to provide name information. In other words, the first one can perform read/write operations, while the second one is read-only.
Once pam_mkhomedir.so
has retrieved the path to the user's home directory, all it has to do is check whether or not it exists, and create it if it does not:
/* Stat the home directory, if something exists then we
* assume it is correct and return a success. */
if(stat(pwd->pw_dir, &st) == 0) return PAM_SUCCESS;
return create_homedir(..., pwd, ...);
The create_homedir
function is defined by the module itself, and it is a bit too long for me to paste it here. Just see it as a big mkdir(2)
call, which handles specific cases and makes sure everything goes smoothly. If you're interested in more details, have a look at pam_mkhomedir.so
's source code. I used this version of it for my answer (it was written by Jason Gunthorpe, whose name is also on my pam_mkhomedir.so
manpage).
Now, as far as I'm concerned, I think the guide you followed is a little incomplete, or at least, the MySQL table it has you create is:
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | UNI | NULL | |
| pass | varchar(50) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
This table is probably detailed enough for VSFTPd to work. Since it is configured with a home root, it can easily determine a user's home directory: $ftp_root/username
. This is actually set with the local_root
parameter:
local_root=/home/vsftpd/$USER
However, pam_mkhomedir.so
is not VSFTPd. It doesn't use this mechanism, but relies on NSS (through getpwnam(3)
). The problem is: your MySQL table does not provide enough information for NSS to fill the struct passwd
we saw earlier. In order to have NSS use MySQL as a source, you'll need to install nss-mysql, which requires a larger MySQL table. This will require adjustments in your VSFTPd configuration, but you should have no problem in having VSFTPd and nss-mysql cohabitate.
This directory gives an example for a minimal nss-mysql setup. The MySQL table for users is defined as follows:
+-----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | | NULL | |
| username_canonical | varchar(255) | NO | UNI | NULL | |
| email | varchar(255) | NO | | NULL | |
| email_canonical | varchar(255) | NO | UNI | NULL | |
| enabled | tinyint(1) | NO | | NULL | |
| salt | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
| last_login | datetime | YES | | NULL | |
| locked | tinyint(1) | NO | | NULL | |
| expired | tinyint(1) | NO | | NULL | |
| expires_at | datetime | YES | | NULL | |
| confirmation_token | varchar(255) | YES | | NULL | |
| password_requested_at | datetime | YES | | NULL | |
| roles | longtext | NO | | NULL | |
| credentials_expired | tinyint(1) | NO | | NULL | |
| credentials_expire_at | datetime | YES | | NULL | |
+-----------------------+--------------+------+-----+---------+----------------+
Now, you might not need all these fields yourself, but keep in mind that struct passwd
structure we saw earlier, and make sure nss-mysql has enough data to fill it :) Besides, the nss-mysql configuration files are flexible enough for you to use default values for anything.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
As you can see, pam_mkhomedir.so
acts at the session level. This means that it acts after the user has been authenticated (by the auth
facility). To do so, it defines the following PAM-specific function :
PAM_EXTERN
int pam_sm_open_session(pam_handle_t * pamh, int flags,
int argc, const char **argv);
As I said, this function is called when the user has been authenticated. Therefore, when it retrieves the PAM user handle...
/* Determine the user name so we can get the home directory */
retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
... it gets access to the name of an authenticated, existing user. With this information, the module will be able to retrieve what it needs (the path to a home directory) through a simple getpwnam(3)
library call:
/* Get the password entry */
pwd = getpwnam(user);
This will return the following structure, filled with information about the user:
struct passwd
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
;
Now, if you wonder where this information is coming from, have a look at /etc/nsswitch.conf
. The Name Service Switch (NSS) is here to provide information regarding names in general (which can be usernames, aliases, groups, hosts, ... see nsswitch.conf(5)
for more details). If the guide you followed is complete enough, it should have had you configure both PAM and NSS: the first handles authentication and account/session management, while the other is merely here to provide name information. In other words, the first one can perform read/write operations, while the second one is read-only.
Once pam_mkhomedir.so
has retrieved the path to the user's home directory, all it has to do is check whether or not it exists, and create it if it does not:
/* Stat the home directory, if something exists then we
* assume it is correct and return a success. */
if(stat(pwd->pw_dir, &st) == 0) return PAM_SUCCESS;
return create_homedir(..., pwd, ...);
The create_homedir
function is defined by the module itself, and it is a bit too long for me to paste it here. Just see it as a big mkdir(2)
call, which handles specific cases and makes sure everything goes smoothly. If you're interested in more details, have a look at pam_mkhomedir.so
's source code. I used this version of it for my answer (it was written by Jason Gunthorpe, whose name is also on my pam_mkhomedir.so
manpage).
Now, as far as I'm concerned, I think the guide you followed is a little incomplete, or at least, the MySQL table it has you create is:
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | UNI | NULL | |
| pass | varchar(50) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
This table is probably detailed enough for VSFTPd to work. Since it is configured with a home root, it can easily determine a user's home directory: $ftp_root/username
. This is actually set with the local_root
parameter:
local_root=/home/vsftpd/$USER
However, pam_mkhomedir.so
is not VSFTPd. It doesn't use this mechanism, but relies on NSS (through getpwnam(3)
). The problem is: your MySQL table does not provide enough information for NSS to fill the struct passwd
we saw earlier. In order to have NSS use MySQL as a source, you'll need to install nss-mysql, which requires a larger MySQL table. This will require adjustments in your VSFTPd configuration, but you should have no problem in having VSFTPd and nss-mysql cohabitate.
This directory gives an example for a minimal nss-mysql setup. The MySQL table for users is defined as follows:
+-----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | | NULL | |
| username_canonical | varchar(255) | NO | UNI | NULL | |
| email | varchar(255) | NO | | NULL | |
| email_canonical | varchar(255) | NO | UNI | NULL | |
| enabled | tinyint(1) | NO | | NULL | |
| salt | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
| last_login | datetime | YES | | NULL | |
| locked | tinyint(1) | NO | | NULL | |
| expired | tinyint(1) | NO | | NULL | |
| expires_at | datetime | YES | | NULL | |
| confirmation_token | varchar(255) | YES | | NULL | |
| password_requested_at | datetime | YES | | NULL | |
| roles | longtext | NO | | NULL | |
| credentials_expired | tinyint(1) | NO | | NULL | |
| credentials_expire_at | datetime | YES | | NULL | |
+-----------------------+--------------+------+-----+---------+----------------+
Now, you might not need all these fields yourself, but keep in mind that struct passwd
structure we saw earlier, and make sure nss-mysql has enough data to fill it :) Besides, the nss-mysql configuration files are flexible enough for you to use default values for anything.
session required pam_mkhomedir.so skel=/etc/ftp/ umask=0022
As you can see, pam_mkhomedir.so
acts at the session level. This means that it acts after the user has been authenticated (by the auth
facility). To do so, it defines the following PAM-specific function :
PAM_EXTERN
int pam_sm_open_session(pam_handle_t * pamh, int flags,
int argc, const char **argv);
As I said, this function is called when the user has been authenticated. Therefore, when it retrieves the PAM user handle...
/* Determine the user name so we can get the home directory */
retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
... it gets access to the name of an authenticated, existing user. With this information, the module will be able to retrieve what it needs (the path to a home directory) through a simple getpwnam(3)
library call:
/* Get the password entry */
pwd = getpwnam(user);
This will return the following structure, filled with information about the user:
struct passwd
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
;
Now, if you wonder where this information is coming from, have a look at /etc/nsswitch.conf
. The Name Service Switch (NSS) is here to provide information regarding names in general (which can be usernames, aliases, groups, hosts, ... see nsswitch.conf(5)
for more details). If the guide you followed is complete enough, it should have had you configure both PAM and NSS: the first handles authentication and account/session management, while the other is merely here to provide name information. In other words, the first one can perform read/write operations, while the second one is read-only.
Once pam_mkhomedir.so
has retrieved the path to the user's home directory, all it has to do is check whether or not it exists, and create it if it does not:
/* Stat the home directory, if something exists then we
* assume it is correct and return a success. */
if(stat(pwd->pw_dir, &st) == 0) return PAM_SUCCESS;
return create_homedir(..., pwd, ...);
The create_homedir
function is defined by the module itself, and it is a bit too long for me to paste it here. Just see it as a big mkdir(2)
call, which handles specific cases and makes sure everything goes smoothly. If you're interested in more details, have a look at pam_mkhomedir.so
's source code. I used this version of it for my answer (it was written by Jason Gunthorpe, whose name is also on my pam_mkhomedir.so
manpage).
Now, as far as I'm concerned, I think the guide you followed is a little incomplete, or at least, the MySQL table it has you create is:
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | UNI | NULL | |
| pass | varchar(50) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
This table is probably detailed enough for VSFTPd to work. Since it is configured with a home root, it can easily determine a user's home directory: $ftp_root/username
. This is actually set with the local_root
parameter:
local_root=/home/vsftpd/$USER
However, pam_mkhomedir.so
is not VSFTPd. It doesn't use this mechanism, but relies on NSS (through getpwnam(3)
). The problem is: your MySQL table does not provide enough information for NSS to fill the struct passwd
we saw earlier. In order to have NSS use MySQL as a source, you'll need to install nss-mysql, which requires a larger MySQL table. This will require adjustments in your VSFTPd configuration, but you should have no problem in having VSFTPd and nss-mysql cohabitate.
This directory gives an example for a minimal nss-mysql setup. The MySQL table for users is defined as follows:
+-----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | | NULL | |
| username_canonical | varchar(255) | NO | UNI | NULL | |
| email | varchar(255) | NO | | NULL | |
| email_canonical | varchar(255) | NO | UNI | NULL | |
| enabled | tinyint(1) | NO | | NULL | |
| salt | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
| last_login | datetime | YES | | NULL | |
| locked | tinyint(1) | NO | | NULL | |
| expired | tinyint(1) | NO | | NULL | |
| expires_at | datetime | YES | | NULL | |
| confirmation_token | varchar(255) | YES | | NULL | |
| password_requested_at | datetime | YES | | NULL | |
| roles | longtext | NO | | NULL | |
| credentials_expired | tinyint(1) | NO | | NULL | |
| credentials_expire_at | datetime | YES | | NULL | |
+-----------------------+--------------+------+-----+---------+----------------+
Now, you might not need all these fields yourself, but keep in mind that struct passwd
structure we saw earlier, and make sure nss-mysql has enough data to fill it :) Besides, the nss-mysql configuration files are flexible enough for you to use default values for anything.
edited Jul 11 '15 at 1:35
slmâ¦
241k66501669
241k66501669
answered May 15 '15 at 8:04
John WH Smith
9,53314051
9,53314051
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f181866%2fdyanamically-creating-directories-with-pam-mkhomedir-and-mysql-for-vsftpd%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password