*/
#include "pam_winbind.h"
+#include "lib/util/setid.h"
enum pam_winbind_request_type
{
if (tiniparser_getboolean(d, "global:mkhomedir", false)) {
ctrl |= WINBIND_MKHOMEDIR;
+ if (tiniparser_getboolean(d, "global:mkhomedir_as_user", false)) {
+ ctrl |= WINBIND_MKHOMEDIR_AS_USER;
+ }
}
if (tiniparser_getboolean(d, "global:pwd_change_prompt", false)) {
ctrl |= WINBIND_CACHED_LOGIN;
else if (!strcasecmp(*v, "mkhomedir"))
ctrl |= WINBIND_MKHOMEDIR;
+ else if (!strcasecmp(*v, "mkhomedir_as_user"))
+ ctrl |= WINBIND_MKHOMEDIR_AS_USER;
else if (!strncasecmp(*v, "warn_pwd_expire",
strlen("warn_pwd_expire")))
ctrl |= WINBIND_WARN_PWD_EXPIRE;
}
_pam_log_debug(ctx, LOG_DEBUG, "homedir is: %s", pwd->pw_dir);
+ if (ctx->ctrl & WINBIND_MKHOMEDIR_AS_USER) {
+ uid_t saved_uid = geteuid();
+ gid_t saved_gid = getegid();
+
+ ret = setegid(pwd->pw_gid);
+ if (ret != 0) {
+ _pam_log(ctx, LOG_ERR, "setegid(%u) failed - %s",
+ (unsigned)pwd->pw_gid, strerror(errno));
+ return PAM_SERVICE_ERR;
+ }
+
+ ret = seteuid(pwd->pw_uid);
+ if (ret != 0) {
+ setegid(saved_gid);
+ _pam_log(ctx, LOG_ERR, "seteuid(%u) failed - %s",
+ (unsigned)pwd->pw_uid, strerror(errno));
+ return PAM_SERVICE_ERR;
+ }
+ ret = _pam_create_homedir(ctx, pwd->pw_dir, 0700);
+ seteuid(saved_uid);
+ setegid(saved_gid);
+ return ret;
+ }
+
ret = _pam_create_homedir(ctx, pwd->pw_dir, 0700);
if (ret == PAM_SUCCESS) {
ret = _pam_chown_homedir(ctx, pwd->pw_dir,