summaryrefslogtreecommitdiff
path: root/Linux-PAM/modules/pam_mkhomedir/pam_mkhomedir.c
diff options
context:
space:
mode:
Diffstat (limited to 'Linux-PAM/modules/pam_mkhomedir/pam_mkhomedir.c')
-rw-r--r--Linux-PAM/modules/pam_mkhomedir/pam_mkhomedir.c194
1 files changed, 169 insertions, 25 deletions
diff --git a/Linux-PAM/modules/pam_mkhomedir/pam_mkhomedir.c b/Linux-PAM/modules/pam_mkhomedir/pam_mkhomedir.c
index 9a4640dd..f63177bf 100644
--- a/Linux-PAM/modules/pam_mkhomedir/pam_mkhomedir.c
+++ b/Linux-PAM/modules/pam_mkhomedir/pam_mkhomedir.c
@@ -4,10 +4,10 @@
when the session begins. This allows users to be present in central
database (such as nis, kerb or ldap) without using a distributed
file system or pre-creating a large number of directories.
-
+
Here is a sample /etc/pam.d/login file for Debian GNU/Linux
2.1:
-
+
auth requisite pam_securetty.so
auth sufficient pam_ldap.so
auth required pam_pwdb.so
@@ -19,11 +19,11 @@
session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
session required pam_pwdb.so
session optional pam_lastlog.so
- password required pam_pwdb.so
-
+ password required pam_pwdb.so
+
Released under the GNU LGPL version 2 or later
Originally written by Jason Gunthorpe <jgg@debian.org> Feb 1999
- Structure taken from pam_lastlogin by Andrew Morgan
+ Structure taken from pam_lastlogin by Andrew Morgan
<morgan@parc.power.net> 1996
*/
@@ -51,6 +51,8 @@
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
+#include <security/_pam_modutil.h>
+
/* argument parsing */
#define MKHOMEDIR_DEBUG 020 /* keep quiet about things */
@@ -98,8 +100,8 @@ static int _pam_parse(int flags, int argc, const char **argv)
return ctrl;
}
-/* This common function is used to send a message to the applications
- conversion function. Our only use is to ask the application to print
+/* This common function is used to send a message to the applications
+ conversion function. Our only use is to ask the application to print
an informative message that we are creating a home directory */
static int converse(pam_handle_t * pamh, int ctrl, int nargs
,struct pam_message **message
@@ -111,7 +113,7 @@ static int converse(pam_handle_t * pamh, int ctrl, int nargs
D(("begin to converse"));
retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
- if (retval == PAM_SUCCESS)
+ if (retval == PAM_SUCCESS && conv)
{
retval = conv->conv(nargs, (const struct pam_message **) message
@@ -130,6 +132,8 @@ static int converse(pam_handle_t * pamh, int ctrl, int nargs
{
_log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
,pam_strerror(pamh, retval));
+ if (retval == PAM_SUCCESS)
+ retval = PAM_BAD_ITEM; /* conv was NULL */
}
D(("ready to return from module conversation"));
@@ -187,9 +191,9 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
/* Create the new directory */
if (mkdir(dest,0700) != 0)
{
- _log_err(LOG_DEBUG, "unable to create directory %s",source);
+ _log_err(LOG_DEBUG, "unable to create directory %s",dest);
return PAM_PERM_DENIED;
- }
+ }
if (chmod(dest,0777 & (~UMask)) != 0 ||
chown(dest,pwd->pw_uid,pwd->pw_gid) != 0)
{
@@ -212,12 +216,19 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
}
for (Dir = readdir(D); Dir != 0; Dir = readdir(D))
- {
+ {
int SrcFd;
int DestFd;
int Res;
struct stat St;
+#ifndef PATH_MAX
+ char *newsource = NULL, *newdest = NULL;
+ /* track length of buffers */
+ int nslen = 0, ndlen = 0;
+ int slen = strlen(source), dlen = strlen(dest);
+#else
char newsource[PATH_MAX], newdest[PATH_MAX];
+#endif
/* Skip some files.. */
if (strcmp(Dir->d_name,".") == 0 ||
@@ -225,37 +236,124 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
continue;
/* Determine what kind of file it is. */
+#ifndef PATH_MAX
+ nslen = slen + strlen(Dir->d_name) + 2;
+
+ if (nslen <= 0)
+ return PAM_BUF_ERR;
+
+ if ( (newsource = malloc(nslen)) == NULL )
+ return PAM_BUF_ERR;
+
+ sprintf(newsource, "%s/%s", source, Dir->d_name);
+#else
snprintf(newsource,sizeof(newsource),"%s/%s",source,Dir->d_name);
+#endif
+
if (lstat(newsource,&St) != 0)
+#ifndef PATH_MAX
+ {
+ free(newsource);
+ newsource = NULL;
continue;
+ }
+#else
+ continue;
+#endif
+
/* We'll need the new file's name. */
+#ifndef PATH_MAX
+ ndlen = dlen + strlen(Dir->d_name)+2;
+
+ if (ndlen <= 0)
+ return PAM_BUF_ERR;
+
+ if ( (newdest = malloc(ndlen)) == NULL ) {
+ free(newsource);
+ return PAM_BUF_ERR;
+ }
+
+ sprintf(newdest, "%s/%s", dest, Dir->d_name);
+#else
snprintf(newdest,sizeof(newdest),"%s/%s",dest,Dir->d_name);
+#endif
/* If it's a directory, recurse. */
if (S_ISDIR(St.st_mode))
{
- create_homedir(pamh, ctrl, pwd, newsource, newdest);
+ int retval = create_homedir(pamh, ctrl, pwd, newsource, newdest);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+
+ if (retval != PAM_SUCCESS) {
+ closedir(D);
+ return retval;
+ }
continue;
}
/* If it's a symlink, create a new link. */
if (S_ISLNK(St.st_mode))
{
+ int pointedlen = 0;
+#ifndef PATH_MAX
+ char *pointed = NULL;
+ {
+ int size = 100;
+
+ while (1) {
+ pointed = (char *) malloc(size);
+ if ( ! pointed ) {
+ free(newsource);
+ free(newdest);
+ return PAM_BUF_ERR;
+ }
+ pointedlen = readlink (newsource, pointed, size);
+ if ( pointedlen < 0 ) break;
+ if ( pointedlen < size ) break;
+ free (pointed);
+ size *= 2;
+ }
+ }
+ if ( pointedlen < 0 )
+ free(pointed);
+ else
+ pointed[pointedlen] = 0;
+#else
char pointed[PATH_MAX];
memset(pointed, 0, sizeof(pointed));
- if(readlink(newsource, pointed, sizeof(pointed) - 1) != -1)
- {
+
+ pointedlen = readlink(newsource, pointed, sizeof(pointed) - 1);
+#endif
+
+ if ( pointedlen >= 0 ) {
if(symlink(pointed, newdest) == 0)
{
if (lchown(newdest,pwd->pw_uid,pwd->pw_gid) != 0)
{
- _log_err(LOG_DEBUG, "unable to chang perms on link %s",
+ closedir(D);
+ _log_err(LOG_DEBUG, "unable to change perms on link %s",
newdest);
+#ifndef PATH_MAX
+ free(pointed);
+ free(newsource);
+ free(newdest);
+#endif
return PAM_PERM_DENIED;
}
}
+#ifndef PATH_MAX
+ free(pointed);
+#endif
}
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
continue;
}
@@ -263,13 +361,24 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
* the new device node, FIFO, or whatever it is. */
if (!S_ISREG(St.st_mode))
{
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
continue;
}
/* Open the source file */
if ((SrcFd = open(newsource,O_RDONLY)) < 0 || fstat(SrcFd,&St) != 0)
{
+ closedir(D);
_log_err(LOG_DEBUG, "unable to open src file %s",newsource);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+
return PAM_PERM_DENIED;
}
stat(newsource,&St);
@@ -278,7 +387,13 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
if ((DestFd = open(newdest,O_WRONLY | O_TRUNC | O_CREAT,0600)) < 0)
{
close(SrcFd);
+ closedir(D);
_log_err(LOG_DEBUG, "unable to open dest file %s",newdest);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
return PAM_PERM_DENIED;
}
@@ -290,26 +405,55 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
{
close(SrcFd);
close(DestFd);
+ closedir(D);
_log_err(LOG_DEBUG, "unable to chang perms on copy %s",newdest);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+
return PAM_PERM_DENIED;
}
/* Copy the file */
do
{
- Res = read(SrcFd,remark,sizeof(remark));
- if (Res < 0 || write(DestFd,remark,Res) != Res)
- {
- close(SrcFd);
- close(DestFd);
- _log_err(LOG_DEBUG, "unable to perform IO");
- return PAM_PERM_DENIED;
+ Res = _pammodutil_read(SrcFd,remark,sizeof(remark));
+
+ if (Res == 0)
+ continue;
+
+ if (Res > 0) {
+ if (_pammodutil_write(DestFd,remark,Res) == Res)
+ continue;
}
+
+ /* If we get here, pammodutil_read returned a -1 or
+ _pammodutil_write returned something unexpected. */
+ close(SrcFd);
+ close(DestFd);
+ closedir(D);
+ _log_err(LOG_DEBUG, "unable to perform IO");
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+
+ return PAM_PERM_DENIED;
}
while (Res != 0);
close(SrcFd);
close(DestFd);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+
}
+ closedir(D);
return PAM_SUCCESS;
}
@@ -324,7 +468,7 @@ int pam_sm_open_session(pam_handle_t * pamh, int flags, int argc
const char *user;
const struct passwd *pwd;
struct stat St;
-
+
/* Parse the flag values */
ctrl = _pam_parse(flags, argc, argv);
@@ -337,7 +481,7 @@ int pam_sm_open_session(pam_handle_t * pamh, int flags, int argc
}
/* Get the password entry */
- pwd = getpwnam(user);
+ pwd = _pammodutil_getpwnam (pamh, user);
if (pwd == NULL)
{
D(("couldn't identify user %s", user));
@@ -353,7 +497,7 @@ int pam_sm_open_session(pam_handle_t * pamh, int flags, int argc
}
/* Ignore */
-PAM_EXTERN
+PAM_EXTERN
int pam_sm_close_session(pam_handle_t * pamh, int flags, int argc
,const char **argv)
{