Русаков Денис
2008-Oct-21 10:21 UTC
[Samba] Create user home directory or user-own folder on samba server on first login to samba
Hello, I'd like to create user home directory or user-own folder on samba server on first login to samba without using PAM, so how could I do this? Thank you, Denis
Michael Heydon
2008-Oct-22 00:17 UTC
[Samba] Create user home directory or user-own folder on samba server on first login to samba
??????? ????? wrote:> I'd like to create user home directory or user-own folder on samba server on first login to samba without using PAM >I use this along with a "root preexec" (and "preexec close") setting on the homes share. *Michael Heydon - IT Administrator * michaelh@jaswin.com.au <mailto:michaelh@jaswin.com.au> -------------- next part -------------- /* * Program Name: smbmkhome * Version: 1.0 * Author: Michael Heydon * Purpose: This program is designed to be run by samba prior to a user * accessing their home directory. Since the users are set up in LDAP * it is possible (probable) that their home directory was not created * when their account was. This program will create the user's home * directory and fix ownership and permissions if necessary. * * The program should be called with 1 parameter * * smbmkhome <username> * * <username> is the user to create/fix the home directory for. * * smbmkhome will return: 0 - success * 1 - incorrect parameters * 2 - invalid user * 3 - home exists but is not a directory * 4 - mkdir/chown failed * * Notes: compile with "gcc -o smbmkhome smbmkhome.c" * tested under slackware linux 10.2 * requires cpio to copy skel when creating a directory */ #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <pwd.h> void printUsage(char* argv0); int createHomeDir(struct passwd* user, char* skel); void fixPerms(struct passwd* user); int main (int argc, char* argv[]) { char* skel = "/etc/skel"; struct passwd* userpw = 0; struct stat dirstat; char* homedir = 0; int returnval = 0; if ( argc != 2 ) { printUsage(argv[0]); returnval = 1; } else { userpw = getpwnam(argv[1]); if ( userpw != 0 ) { homedir = userpw->pw_dir; } else { // Since this is unlikely to occur if the program is being called by // samba as I intended we will allow a little bit of user interaction // here. printf ("%s: User does not exist.\n", argv[0]); returnval = 2; } } if ( returnval == 0 ) if ( stat(homedir, &dirstat) == 0 ) { if ( (dirstat.st_mode & S_IFMT) == S_IFDIR ) { // Make sure the user and the users primary group are the owners of the // home directory and make sure at least the user has RWX permissions. // // The last comparison isn't terrible intuitive it just happens that // the bitmask S_IRWXU is exactly equal to the bits we want set. Rather // than or'ing together the bits for RWX to get exactly the same value // I decided to use the mask itself. if ( (dirstat.st_uid != userpw->pw_uid) || \ (dirstat.st_gid != userpw->pw_gid) || \ ( (dirstat.st_mode & S_IRWXU) != S_IRWXU) ) fixPerms(userpw); } else { // stat returned, meaning the home "directory" exists on the FS, but // the st_mode variable indicates that its not a directory. Oops :/ // We won't try and force things because this could be used by admins // to stop a particular user from having a home directory (guest users // etc). returnval = 3; } } else { // home directory does not exist at all, try and create it and chown it // to the user and their primary group. copy skel to the new home dir if // possible but dont worry if that bit fails. if ( ! createHomeDir(userpw, skel) == 0 ) returnval=4; } return returnval; } void printUsage (char* argv0) { printf ("Usage: %s <username>\n\n", argv0); printf ("Create/fix a user's home directory (prior to accessing via samba).\n"); } int createHomeDir(struct passwd* user, char* skel) { int returnval=0; char command[255]; if ( (mkdir(user->pw_dir, 0755) == 0) ) { returnval=chown(user->pw_dir, user->pw_uid, user->pw_gid); } else { returnval=1; } if ( returnval == 0 ) { // Don't worry if this fails, the directory exists and is owned by the user // this is really just a courtesy. sprintf(command, "cd %s && find . -print | cpio -pd %s 2>&1 > /dev/null" ,skel, user->pw_dir); system(command); sprintf(command, "chown -R %s. %s", user->pw_name, user->pw_dir); system(command); } return returnval; } void fixPerms(struct passwd* user) { // We don't return anything here, since the directory already exists its // possible that who ever created the directory set things up in such a way // that this function fails but the share works the way they want, we don't // want to tell samba to drop the user's connection just because their admin // is being wierd :) if ( (chmod(user->pw_dir, 0755) == 0) ) { chown(user->pw_dir, user->pw_uid, user->pw_gid); } }