[SCM] Samba Shared Repository - branch master updated - 5b75aa34069d488d23e880393d4280cbe85cc5c6

Günther Deschner gd at samba.org
Fri Oct 10 13:43:33 GMT 2008


The branch, master has been updated
       via  5b75aa34069d488d23e880393d4280cbe85cc5c6 (commit)
       via  042df7f0b78d60a721fa35c42e950774261cea1d (commit)
      from  d9efd52fd09af752b3b7fae2a88a522e05e7f672 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 5b75aa34069d488d23e880393d4280cbe85cc5c6
Author: Günther Deschner <gd at samba.org>
Date:   Thu Aug 14 14:41:50 2008 +0200

    pam_winbind: document mkhomedir option.
    
    Guenther

commit 042df7f0b78d60a721fa35c42e950774261cea1d
Author: Günther Deschner <gd at samba.org>
Date:   Thu Aug 14 14:39:52 2008 +0200

    pam_winbind: re-add mkhomedir option.
    
    Guenther

-----------------------------------------------------------------------

Summary of changes:
 docs-xml/manpages-3/pam_winbind.7.xml |    8 ++
 examples/pam_winbind/pam_winbind.conf |    3 +
 source3/nsswitch/pam_winbind.c        |  135 ++++++++++++++++++++++++++++++++-
 source3/nsswitch/pam_winbind.h        |    1 +
 4 files changed, 144 insertions(+), 3 deletions(-)


Changeset truncated at 500 lines:

diff --git a/docs-xml/manpages-3/pam_winbind.7.xml b/docs-xml/manpages-3/pam_winbind.7.xml
index cf7fd5a..7f233c1 100644
--- a/docs-xml/manpages-3/pam_winbind.7.xml
+++ b/docs-xml/manpages-3/pam_winbind.7.xml
@@ -134,6 +134,14 @@
 		</para></listitem>
 		</varlistentry>
 
+		<varlistentry>
+		<term>mkhomedir</term>
+		<listitem><para>
+		Create homedirectory for a user on-the-fly, option is valid in
+		PAM session block.
+		</para></listitem>
+		</varlistentry>
+
 		</variablelist>
 
 
diff --git a/examples/pam_winbind/pam_winbind.conf b/examples/pam_winbind/pam_winbind.conf
index a9e02a8..dd0b112 100644
--- a/examples/pam_winbind/pam_winbind.conf
+++ b/examples/pam_winbind/pam_winbind.conf
@@ -33,3 +33,6 @@
 
 # omit pam conversations
 ;silent = no
+
+# create homedirectory on the fly
+;mkhomedir = no
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
index a9d6aa6..8d8868d 100644
--- a/source3/nsswitch/pam_winbind.c
+++ b/source3/nsswitch/pam_winbind.c
@@ -437,6 +437,10 @@ static int _pam_parse(const pam_handle_t *pamh,
 		ctrl |= WINBIND_WARN_PWD_EXPIRE;
 	}
 
+	if (iniparser_getboolean(d, "global:mkhomedir", false)) {
+		ctrl |= WINBIND_MKHOMEDIR;
+	}
+
 config_from_pam:
 	/* step through arguments */
 	for (i=argc,v=argv; i-- > 0; ++v) {
@@ -469,6 +473,8 @@ config_from_pam:
 			ctrl |= WINBIND_KRB5_CCACHE_TYPE;
 		else if (!strcasecmp(*v, "cached_login"))
 			ctrl |= WINBIND_CACHED_LOGIN;
+		else if (!strcasecmp(*v, "mkhomedir"))
+			ctrl |= WINBIND_MKHOMEDIR;
 		else {
 			__pam_log(pamh, ctrl, LOG_ERR,
 				 "pam_parse: unknown option: %s", *v);
@@ -1378,6 +1384,127 @@ static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx,
 	return NULL;
 }
 
+static int _pam_create_homedir(struct pwb_context *ctx,
+			       const char *dirname,
+			       mode_t mode)
+{
+	struct stat sbuf;
+
+	if (stat(dirname, &sbuf) == 0) {
+		return PAM_SUCCESS;
+	}
+
+	if (mkdir(dirname, mode) != 0) {
+
+		_make_remark_format(ctx, PAM_TEXT_INFO,
+				    "Creating directory: %s failed: %s",
+				    dirname, strerror(errno));
+		_pam_log(ctx, LOG_ERR, "could not create dir: %s (%s)",
+		 dirname, strerror(errno));
+		 return PAM_PERM_DENIED;
+	}
+
+	return PAM_SUCCESS;
+}
+
+static int _pam_chown_homedir(struct pwb_context *ctx,
+			      const char *dirname,
+			      uid_t uid,
+			      gid_t gid)
+{
+	if (chown(dirname, uid, gid) != 0) {
+		_pam_log(ctx, LOG_ERR, "failed to chown user homedir: %s (%s)",
+			 dirname, strerror(errno));
+		return PAM_PERM_DENIED;
+	}
+
+	return PAM_SUCCESS;
+}
+
+static int _pam_mkhomedir(struct pwb_context *ctx)
+{
+	struct passwd *pwd = NULL;
+	char *token = NULL;
+	char *create_dir = NULL;
+	char *user_dir = NULL;
+	int ret;
+	const char *username;
+	mode_t mode = 0700;
+	char *safe_ptr = NULL;
+	char *p = NULL;
+
+	/* Get the username */
+	ret = pam_get_user(ctx->pamh, &username, NULL);
+	if ((ret != PAM_SUCCESS) || (!username)) {
+		_pam_log_debug(ctx, LOG_DEBUG, "can not get the username");
+		return PAM_SERVICE_ERR;
+	}
+
+	pwd = getpwnam(username);
+	if (pwd == NULL) {
+		_pam_log_debug(ctx, LOG_DEBUG, "can not get the username");
+		return PAM_USER_UNKNOWN;
+	}
+	_pam_log_debug(ctx, LOG_DEBUG, "homedir is: %s", pwd->pw_dir);
+
+	ret = _pam_create_homedir(ctx, pwd->pw_dir, 0700);
+	if (ret == PAM_SUCCESS) {
+		ret = _pam_chown_homedir(ctx, pwd->pw_dir,
+					 pwd->pw_uid,
+					 pwd->pw_gid);
+	}
+
+	if (ret == PAM_SUCCESS) {
+		return ret;
+	}
+
+	/* maybe we need to create parent dirs */
+	create_dir = talloc_strdup(ctx, "/");
+	if (!create_dir) {
+		return PAM_BUF_ERR;
+	}
+
+	/* find final directory */
+	user_dir = strrchr(pwd->pw_dir, '/');
+	if (!user_dir) {
+		return PAM_BUF_ERR;
+	}
+	user_dir++;
+
+	_pam_log(ctx, LOG_DEBUG, "final directory: %s", user_dir);
+
+	p = pwd->pw_dir;
+
+	while ((token = strtok_r(p, "/", &safe_ptr)) != NULL) {
+
+		mode = 0755;
+
+		p = NULL;
+
+		_pam_log_debug(ctx, LOG_DEBUG, "token is %s", token);
+
+		create_dir = talloc_asprintf_append(create_dir, "%s/", token);
+		if (!create_dir) {
+			return PAM_BUF_ERR;
+		}
+		_pam_log_debug(ctx, LOG_DEBUG, "current_dir is %s", create_dir);
+
+		if (strcmp(token, user_dir) == 0) {
+			_pam_log_debug(ctx, LOG_DEBUG, "assuming last directory: %s", token);
+			mode = 0700;
+		}
+
+		ret = _pam_create_homedir(ctx, create_dir, mode);
+		if (ret) {
+			return ret;
+		}
+	}
+
+	return _pam_chown_homedir(ctx, create_dir,
+				  pwd->pw_uid,
+				  pwd->pw_gid);
+}
+
 /* talk to winbindd */
 static int winbind_auth_request(struct pwb_context *ctx,
 				const char *user,
@@ -2470,7 +2597,7 @@ PAM_EXTERN
 int pam_sm_open_session(pam_handle_t *pamh, int flags,
 			int argc, const char **argv)
 {
-	int ret = PAM_SYSTEM_ERR;
+	int ret = PAM_SUCCESS;
 	struct pwb_context *ctx = NULL;
 
 	ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
@@ -2480,8 +2607,10 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
 
 	_PAM_LOG_FUNCTION_ENTER("pam_sm_open_session", ctx);
 
-	ret = PAM_SUCCESS;
-
+	if (ctx->ctrl & WINBIND_MKHOMEDIR) {
+		/* check and create homedir */
+		ret = _pam_mkhomedir(ctx);
+	}
  out:
 	_PAM_LOG_FUNCTION_LEAVE("pam_sm_open_session", ctx, ret);
 
diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h
index e7c869c..cb6f450 100644
--- a/source3/nsswitch/pam_winbind.h
+++ b/source3/nsswitch/pam_winbind.h
@@ -99,6 +99,7 @@ do {                             \
 #define WINBIND_SILENT			0x00000800
 #define WINBIND_DEBUG_STATE		0x00001000
 #define WINBIND_WARN_PWD_EXPIRE		0x00002000
+#define WINBIND_MKHOMEDIR		0x00004000
 
 /*
  * here is the string to inform the user that the new passwords they


-- 
Samba Shared Repository


More information about the samba-cvs mailing list