Samba 3.0: profiling not working under Solaris

Pierre Belanger pbelang1 at oss.cantel.rogers.com
Mon Jul 7 11:01:37 GMT 2003


Hi all,

I posted a message here back in January. I was pretty busy since
the past monthssss but I kept an eye on the list. Since Samba 3.0
"final" shall soon be out, it would be a good idea to fix it. I'm
restarting all over since "line numbers" now differs a little bit.

The following is true at least under Solaris (all releases) and
perhaps other OS? Under Solaris, root group ID is 1 . Under HPUX,
it's 3. When profiling is enable under Solaris, smbd reports:

  Jan 14 11:55:56 carnaval smbd[23609]: [ID 702911 daemon.error]
   ERROR:  we did not create the shmem (owned by another user)
  Jan 14 11:55:56 carnaval smbd[23609]: [ID 702911 daemon.error]
   ERROR: failed to setup profiling

* in smbd/server.c line # 688 :

   sec_init(); // ref: lib/util_sec.c that does:

     initial_uid = geteuid();
     initial_gid = getegid();

* in smbd/server.c line # 713:

     gain_root_privilege();
     gain_root_group_privilege();

     Sets uid/gid/egid/euid to 0.

* in smbd/server.c line # 770:

           if (!profile_setup(False)) {
                 DEBUG(0,("ERROR: failed to setup profiling\n"));
                 return -1;

* in profile/profile.c line # 139 (within the profile_setup()
   routine) :

     if (shm_ds.shm_perm.cuid != sec_initial_uid() ||
       shm_ds.shm_perm.cgid != sec_initial_gid()) {
         DEBUG(0,("ERROR: we did not create the shmem (owned by ...

"gain_root_group_privilege" does setegid/setgid to 0.
When profile/profile.c line #139 checks the gid who
created the shared memory, shm_ds.shm_perm.cgid = 0
BUT sec_initial_gid() returns 1 under Solaris. So, smbd
complains that it did not create the shared memory.

I propose the following changes to profile/profile.c, see
attached diff file againts SAMBA_3_0. Also, I added a check
for "EEXIST" after creating the shared memory. This could?
fix the race condition if shmget is "atomic" -- I couldn't
find information on this! I also don't know if EEXIST
exists on "all" OS, but I know it does at least under
Solaris and HPUX. Apply whatever changes you want.

Another "tiny" bug line ~ # 130 in profile/profile.c (it's
fixed in my diff). Also needs to be fixed in SAMBA_2_2 and
HEAD:

---    if ((long)profile_p == -1) {
+++    if ((long)profile_h == -1) {

Thank you,
Pierre B.
-------------- next part --------------
--- source/profile/profile.c.orig	Mon Jul  7 06:47:23 2003
+++ source/profile/profile.c	Fri Jul  4 15:08:55 2003
@@ -106,24 +106,38 @@
 	/* try to use an existing key */
 	shm_id = shmget(PROF_SHMEM_KEY, 0, 0);
 	
-	/* if that failed then create one. There is a race condition here
-	   if we are running from inetd. Bad luck. */
+	/* if that failed then create one. */
 	if (shm_id == -1) {
+
+		static BOOL redo = True;
+
 		if (read_only) return False;
 		shm_id = shmget(PROF_SHMEM_KEY, sizeof(*profile_h), 
 				IPC_CREAT | IPC_EXCL | IPC_PERMS);
-	}
-	
-	if (shm_id == -1) {
-		DEBUG(0,("Can't create or use IPC area. Error was %s\n", 
-			 strerror(errno)));
-		return False;
+
+		if (shm_id == -1) {
+
+			/* Check if we might have run into a race condition when running
+			   from inetd. Bad luck. */
+			if ((errno == EEXIST) && (redo == True)) {
+
+				/* Make sure we don't spin forever - prevent OS bug */
+				redo = False;
+				DEBUG(0,("Can't create or use IPC area. Error was %s\n", 
+				 strerror(errno)));
+				DEBUG(0,("Trying again to use IPC area.\n"));
+		  		goto again;
+			} else {
+				DEBUG(0,("Can't create or use IPC area. Error was %s\n", 
+				 strerror(errno)));
+				return False;
+			}
+		}
 	}   
 	
-	
 	profile_h = (struct profile_header *)shmat(shm_id, 0, 
 						   read_only?SHM_RDONLY:0);
-	if ((long)profile_p == -1) {
+	if ((long)profile_h == -1) {
 		DEBUG(0,("Can't attach to IPC area. Error was %s\n", 
 			 strerror(errno)));
 		return False;
@@ -136,8 +150,14 @@
 		return False;
 	}
 
-	if (shm_ds.shm_perm.cuid != sec_initial_uid() || shm_ds.shm_perm.cgid != sec_initial_gid()) {
-		DEBUG(0,("ERROR: we did not create the shmem (owned by another user)\n"));
+	if (shm_ds.shm_perm.cuid != getuid() ||
+	    shm_ds.shm_perm.cgid != getgid()) {
+		DEBUG(0,("ERROR: we did not create the shmem (owned by uid/gid = %d/%d)\n", shm_ds.shm_perm.cuid, shm_ds.shm_perm.cgid));
+		return False;
+	}
+
+	if (shm_ds.shm_perm.cgid != getgid()) {
+		DEBUG(0,("ERROR: we did not create the shmem (owned by another group)\n"));
 		return False;
 	}
 


More information about the samba-technical mailing list