dyanamically creating directories with pam_mkhomedir and mysql for vsftpd

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite
1












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









share|improve this question



























    up vote
    2
    down vote

    favorite
    1












    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









    share|improve this question

























      up vote
      2
      down vote

      favorite
      1









      up vote
      2
      down vote

      favorite
      1






      1





      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









      share|improve this question















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 45 secs ago









      Rui F Ribeiro

      37.3k1374118




      37.3k1374118










      asked Jan 29 '15 at 20:03









      Code Junkie

      1237




      1237




















          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.






          share|improve this answer






















            Your Answer







            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "106"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            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






























            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.






            share|improve this answer


























              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.






              share|improve this answer
























                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.






                share|improve this answer














                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.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jul 11 '15 at 1:35









                slm♦

                241k66501669




                241k66501669










                answered May 15 '15 at 8:04









                John WH Smith

                9,53314051




                9,53314051



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    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













































































                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Displaying single band from multi-band raster using QGIS

                    How many registers does an x86_64 CPU actually have?