Author: jra
Date: 2006-09-07 04:01:11 +0000 (Thu, 07 Sep 2006)
New Revision: 18200

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=18200

Log:
Experimental code to allow system /etc/krb5.conf to be
overwritten by winbindd. Don't enable this :-).
Jeremy.

Modified:
   branches/SAMBA_3_0/source/libads/kerberos.c


Changeset:
Modified: branches/SAMBA_3_0/source/libads/kerberos.c
===================================================================
--- branches/SAMBA_3_0/source/libads/kerberos.c 2006-09-07 03:44:05 UTC (rev 
18199)
+++ branches/SAMBA_3_0/source/libads/kerberos.c 2006-09-07 04:01:11 UTC (rev 
18200)
@@ -516,15 +516,15 @@
 
 BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char 
*domain, struct in_addr ip)
 {
-       XFILE *xfp = NULL;
        char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir());
+       char *tmpname = NULL;
        char *fname = NULL;
        char *file_contents = NULL;
        char *kdc_ip_string;
        size_t flen = 0;
-       size_t ret;
+       ssize_t ret;
+       int fd;
        char *realm_upper = NULL;
-       int loopcount = 0;
 
        if (!dname) {
                return False;
@@ -537,6 +537,12 @@
                return False;
        }
 
+       tmpname = talloc_asprintf(dname, "%s/smb_tmp_krb5.XXXXXX", 
lp_lockdir());
+       if (!tmpname) {
+               TALLOC_FREE(dname);
+               return False;
+       }
+
        fname = talloc_asprintf(dname, "%s/krb5.conf.%s", dname, domain);
        if (!fname) {
                TALLOC_FREE(dname);
@@ -567,62 +573,77 @@
 
        flen = strlen(file_contents);
 
-       while (loopcount < 10) {
-               SMB_STRUCT_STAT st;
-
-               xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0644);
-               if (!xfp) {
-                       TALLOC_FREE(dname);
-                       return False;
-               }
-               /* Lock the file. */
-               if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) {
-                       unlink(fname);
-                       x_fclose(xfp);
-                       TALLOC_FREE(dname);
-                       return False;
-               }
-
-               /* We got the lock. Is the file still there ? */
-               if (sys_stat(fname,&st)==-1) {
-                       if (errno == ENOENT) {
-                               /* Nope - try again up to 10x */
-                               x_fclose(xfp);
-                               loopcount++;
-                               continue;       
-                       }
-                       unlink(fname);
-                       x_fclose(xfp);
-                       TALLOC_FREE(dname);
-                       return False;
-               }
-               break;
+       fd = smb_mkstemp(tmpname);
+       if (fd == -1) {
+               DEBUG(0,("create_local_private_krb5_conf_for_domain: 
smb_mkstemp failed,"
+                       " for file %s. Errno %s\n",
+                       tmpname, strerror(errno) ));
        }
 
-       ret = x_fwrite(file_contents, 1, flen, xfp);
+       ret = write(fd, file_contents, flen);
        if (flen != ret) {
-               DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fwrite 
failed,"
-                       " returned %u (should be %u). Errno %s\n",
-                       (unsigned int)ret, (unsigned int)flen, strerror(errno) 
));
-               unlink(fname);
-               x_fclose(xfp);
+               DEBUG(0,("create_local_private_krb5_conf_for_domain: write 
failed,"
+                       " returned %d (should be %u). Errno %s\n",
+                       (int)ret, (unsigned int)flen, strerror(errno) ));
+               unlink(tmpname);
+               close(fd);
                TALLOC_FREE(dname);
                return False;
        }
-       if (x_fclose(xfp)==-1) {
-               DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fclose 
failed."
+       if (close(fd)==-1) {
+               DEBUG(0,("create_local_private_krb5_conf_for_domain: close 
failed."
                        " Errno %s\n", strerror(errno) ));
-               unlink(fname);
+               unlink(tmpname);
                TALLOC_FREE(dname);
                return False;
        }
 
+       if (rename(tmpname, fname) == -1) {
+               DEBUG(0,("create_local_private_krb5_conf_for_domain: rename "
+                       "of %s to %s failed. Errno %s\n",
+                       tmpname, fname, strerror(errno) ));
+               unlink(tmpname);
+               TALLOC_FREE(dname);
+               return False;
+       }
+
        DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote "
                "file %s with realm %s KDC = %s\n",
                fname, realm_upper, inet_ntoa(ip) ));
 
        /* Set the environment variable to this file. */
        setenv("KRB5_CONFIG", fname, 1);
+
+#if defined(OVERWRITE_SYSTEM_KRB5_CONF)
+
+       /* Insanity, sheer insanity..... */
+
+       if (symlink(fname, "/etc/krb5.conf") == -1) {
+               if (errno != EEXIST) {
+                       DEBUG(0,("create_local_private_krb5_conf_for_domain: 
symlink "
+                               "of %s to /etc/krb5.conf failed. Errno %s\n",
+                               fname, strerror(errno) ));
+                       TALLOC_FREE(dname);
+                       return True; /* Not a fatal error. */
+               }
+
+               if (unlink("/etc/krb5.conf") == -1) {
+                       DEBUG(0,("create_local_private_krb5_conf_for_domain: 
unlink "
+                               "of /etc/krb5.conf failed. Errno %s\n",
+                               strerror(errno) ));
+                       TALLOC_FREE(dname);
+                       return True; /* Not a fatal error. */
+               }
+               if (symlink(fname, "/etc/krb5.conf") == -1) {
+                       DEBUG(0,("create_local_private_krb5_conf_for_domain: "
+                               "forced symlink of %s to /etc/krb5.conf failed. 
Errno %s\n",
+                               fname, strerror(errno) ));
+                       TALLOC_FREE(dname);
+                       return True; /* Not a fatal error. */
+               }
+       }
+#endif
+
        TALLOC_FREE(dname);
 
        return True;

Reply via email to