[Samba] Create user home directory or user-own folder on samba
server on first login to samba
Michael Heydon
michaelh at jaswin.com.au
Wed Oct 22 00:17:35 GMT 2008
Русаков Денис 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 at jaswin.com.au <mailto:michaelh at 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);
}
}
More information about the samba
mailing list