severity 405880 important
retitle 405880 kde-guidance userconfig breaks login permissions
tags 405880 + patch

thanks

hi,

guidance reported bug, is a bug fixed in 0.6.3. i created a new user with 
0.7.0 and permissions were set correctly. i was able to log into console 
using the new user. Modestas Vainius suggests to change umask to reproduce 
the bug. So umask 0066 breaks file creation, but it isn't guidance fault. 
Current guidance (0.7.0) keep perms as they are. I wasn't able to reproduce it 
until i changed my umask. i reduced severity to important as it isn't 
completely guidance fault. Modestas provided a patch, submitted to upstream. i 
expect to have a proper solution soon :)

cheers,

Fathi
diff -uNr kde-guidance-0.7.0.old/userconfig/unixauthdb.py kde-guidance-0.7.0/userconfig/unixauthdb.py
--- kde-guidance-0.7.0.old/userconfig/unixauthdb.py	2007-01-07 12:26:57.000000000 +0200
+++ kde-guidance-0.7.0/userconfig/unixauthdb.py	2007-01-07 13:35:09.000000000 +0200
@@ -17,10 +17,12 @@
 import fcntl
 import time
 import os
+import os.path
 import stat
 import shutil
 import codecs
 import locale
+import tempfile
 
 ldaperror = ""
 try:
@@ -28,6 +30,20 @@
 except ImportError:
     ldaperror = "The LDAP Python Module is not installed, but needed to use LDAP. Install it."
 
+def createTempFile(origfile):
+    origstat = os.stat(origfile)
+    tmp_prefix = os.path.basename(origfile) + "."
+    tmp_dir = os.path.dirname(origfile)
+    try:
+        ret = tempfile.mkstemp(prefix=tmp_prefix, dir=tmp_dir)
+    except:
+        raise IOError, "Unable to create a new temporary file for " + origfile
+    (fd, tmpfile) = ret
+    shutil.copymode(origfile, tmpfile)
+    os.chown(tmpfile, origstat.st_uid, origstat.st_gid)
+
+    return ret
+
 def getContext(editmode=False):
     """Get a Context object describing the system's authorisation database.
 
@@ -820,54 +836,46 @@
         self._sanityCheck()
 
         # Write out the new password file.        
-        origstat = os.stat(self.__passwordfile)
-        tmpname = self.__passwordfile+".TMP"
-        fd = os.open(tmpname, os.O_CREAT|os.O_WRONLY|os.O_TRUNC, origstat.st_mode)
+        (fd, tmpname) = createTempFile(self.__passwordfile)
         for u in self._users:
             os.write(fd, u._getPasswdEntry().encode(locale.getpreferredencoding(),'replace'))
             #print u._getPasswdEntry()
         os.close(fd)
-        os.chown(tmpname, origstat.st_uid, origstat.st_gid)
         
         # Update the passwd file
         passwordlock = os.open(self.__passwordfile, os.O_WRONLY) # FIXME encoding
         if LockFDWrite(passwordlock)==False:
             raise IOError,"Couldn't get a write lock on "+self.__passwordfile
         try:
-            os.rename(self.__passwordfile+".TMP",self.__passwordfile)
+            os.rename(tmpname, self.__passwordfile)
         finally:
             UnlockFD(passwordlock)
             os.close(passwordlock)
 
         # Write out the new group file
-        origstat = os.stat(self.__groupfile)
-        tmpname = self.__groupfile+".TMP"
-        fd = os.open(tmpname, os.O_CREAT|os.O_WRONLY|os.O_TRUNC, origstat.st_mode)
+        (fd, tmpname) = createTempFile(self.__groupfile)
         for g in self._groups:
             os.write(fd,g._getGroupFileEntry().encode(locale.getpreferredencoding()))
             #print g._getGroupFileEntry()[:-1]
         os.close(fd)
-        os.chown(tmpname, origstat.st_uid, origstat.st_gid)
 
         # Update the group file.
         grouplock = os.open(self.__groupfile, os.O_WRONLY)
         if LockFDWrite(grouplock)==False:
             raise IOError,"Couldn't get write lock on "+self.__groupfile
         try:
-            os.rename(self.__groupfile+".TMP",self.__groupfile)
+            os.rename(tmpname, self.__groupfile)
         finally:
             UnlockFD(grouplock)
             os.close(grouplock)
 
         # Write out the new shadow file
         origstat = os.stat(self.__shadowfile)
-        tmpname = self.__shadowfile+".TMP"
-        fd = os.open(tmpname, os.O_CREAT|os.O_WRONLY|os.O_TRUNC, origstat.st_mode|stat.S_IWUSR)
+        (fd, tmpname) = createTempFile(self.__shadowfile)
         for u in self._users:
             os.write(fd,u._getShadowEntry().encode(locale.getpreferredencoding()))
             #print u._getShadowEntry()[:-1]
         os.close(fd)
-        os.chown(tmpname, origstat.st_uid, origstat.st_gid)
 
         # Update the shadow file.
 
@@ -879,7 +887,7 @@
         if LockFDWrite(shadowlock)==False:
             raise IOError,"Couldn't get write lock on "+self.__shadowfile
         try:
-            os.rename(self.__shadowfile+".TMP",self.__shadowfile)
+            os.rename(tmpname, self.__shadowfile)
         finally:
             UnlockFD(shadowlock)
             os.close(shadowlock)

Reply via email to