KVoort - 2005-11-22

Well I'm sure this has been discussed before, however it remains a major pain in the neck for me. Following is a patch which will allow non-root users to change their passwords. It will also check to be sure that non root users are only changing their own passwords (in case passwd fails in that regard). This patch is against mysql-0.7pre3.

--- pam_mysql.c    2005-11-21 23:44:19.000000000 -0500
+++ pam_mysql.c.mod    2005-11-21 23:44:11.000000000 -0500
@@ -124,6 +124,8 @@
#include <md5.h>
#endif

+#include <pwd.h>
+
#if defined(HAVE_SASL_MD5_H) && (defined(HAVE_CYRUS_SASL_V1) || defined(HAVE_CYRUS_SASL_V2))
#define USE_SASL_MD5
#include <md5global.h>
@@ -3686,11 +3688,11 @@
         syslog(LOG_AUTHPRIV | LOG_ERR, PAM_MYSQL_LOG_PREFIX "pam_sm_chauthtok() called.");
     }

-    if (getuid() != 0) {
-        syslog(LOG_AUTHPRIV | LOG_ERR, PAM_MYSQL_LOG_PREFIX "only super user is allowed to change authentication token.");
-        retval = PAM_PERM_DENIED;
-        goto out;
-    }
+    //    if (getuid() != 0) {
+    //        syslog(LOG_AUTHPRIV | LOG_ERR, PAM_MYSQL_LOG_PREFIX "only super user is allowed to change authentication token.");
+    //        retval = PAM_PERM_DENIED;
+    //        goto out;
+    //    }

     /* Get User */
     if ((retval = pam_get_user(pamh, (PAM_GET_USER_CONST char **)&user,
@@ -3813,16 +3815,31 @@
                 goto out;
         }

+        struct passwd *userinfo;
+        userinfo = getpwuid(getuid());
+        if ( (strncmp(user,userinfo->pw_name,strlen(user)>strlen(userinfo->pw_name)?strlen(user):strlen(userinfo->pw_name))) && getuid()) {
+          printf("You cannot attempt to change another user's password.\n");
+          retval=PAM_AUTHTOK_ERR;
+          goto out;
+            }
+
         if (!(stat & PAM_MYSQL_USER_STAT_NULL_PASSWD)) {
             if (old_passwd == NULL && !ctx->use_first_pass) {
                 char **resps;
-                switch (pam_mysql_converse(ctx, &resps, pamh, 1, PAM_PROMPT_ECHO_OFF, PLEASE_ENTER_OLD_PASSWORD)) {
-                    case PAM_MYSQL_ERR_SUCCESS:
-                        break;
-
-                    default:
-                        retval = PAM_SERVICE_ERR;
-                        goto out;
+                if (getuid()) {
+                  switch (pam_mysql_converse(ctx, &resps, pamh, 1, PAM_PROMPT_ECHO_OFF, PLEASE_ENTER_OLD_PASSWORD)) {
+                  case PAM_MYSQL_ERR_SUCCESS:
+                    break;
+
+                  default:
+                    retval = PAM_SERVICE_ERR;
+                    goto out;
+                  }
+                }
+                else {
+                  retval = PAM_MYSQL_ERR_SUCCESS;
+                  resps = malloc(10);
+                  resps[0] = NULL;
                 }
                 old_passwd = resps[0];
                 old_passwd_should_be_freed = 1;
@@ -3830,13 +3847,13 @@
                 xfree(resps);
             }

-            if (old_passwd == NULL) {
+            if (old_passwd == NULL && getuid()) {
                 retval = PAM_AUTHTOK_ERR;
                 goto out;
             }
         }

-        if (old_passwd != NULL) {
+        if ((old_passwd != NULL) && (getuid()) ) {
             switch (pam_mysql_check_passwd(ctx, user, old_passwd, 0)) {
                 case PAM_MYSQL_ERR_SUCCESS:
                     retval = PAM_SUCCESS;