C code problem

Here’s a snippet of code that I am trying to get to work.


  // call_mount is a flag set by previous tests.  0 means I want to mount the drives.
   if (call_mount == 0) {
        execl("/sbin/mount.cifs","mount.cifs","//Ls420dc48/share","/mnt/Buffalo","nofail","users","credentials=/tmp/.cred","_netdev","file_mode=0777","dir_mode=0777","rw",NULL);
        
        execl("/sbin/mount.cifs","mount.cifs","//RT-AC66R/root","/mnt/Hardin","nofail","users","credentials=/tmp/.cred","_netdev","rw",NULL);

        // We need to change the permissions so the next user can overwrite the file.
        execl("/bin/chmod","chmod","0666",FILE_NAME,NULL);

The first line will work fine., the following two will not execute. I can comment out any two lines and the remaining line will function as it should.

WHY?

How can I correct this?

And, if you’re in the mood, suggest a proper way to trap the error if the mount is already active. A umount and them remount would be the best.

I’m in WAY over my head!

Bart

Yes, you are.

A successful “execl()” is the last thing that you will do in your program. Because the function of execl() is to replace your program with the new one that you are invoking.

You would do better to use system() to invoke those commands.

An additional comment.

Typical use of execl would be something like:


pid = fork();
if ( pid == 0 ) { # here you do the execl in the child process }
else {# here you use wait() or waitpid() to wait for the child to complete}

The documentation I found said not to use system() in a process that was setuid root. The drive I’m mounting is cifs, so I need root. Did I read that wrong?

That is generally good advice.

However, the only way to avoid it is to use fork(), then do the execl() in the newly created child process.

When you use system(), that runs a shell (in a forked child process), and shells might not handle setuid the way that you intended.

Now you might accuse me of heracy here, but why implement these tasks in a c-program?

Actually, all the code I see here looks like a text-book example for a simple shell script.

Additionally, if possible (mountpoint and address/name of share are persistent, which seems to be the case here), configuring /etc/fstab to allow certain users to mount the share (hint: use a specific group) might avoid the “needs root” issue.

Finally, for the “aleady mounted”-issue, you might use “mount | grep <search terms>” or even the program “mountpoint” which is specifically designed for that task.


mount | grep **oot
/dev/sda2 on /boot type ext3 (rw,noatime,nodiratime,data=ordered)

mountpoint /boot/
/boot/ is a mountpoint

umount /boot 

mount | grep **oot

mountpoint /boot/
/boot/ is not a mountpoint

I think you get the idea.****

That’s misleading. Shell does not care about SUID, but shell will (attempt to) interpret arguments to program as shell command line and that may lead to unexpected results. If caller verifies command line and is sure it is properly quoted or does not contain any shell metacharacters, using system is just fine.

I’d say “intentionally vague” rather than “misleading”.

I don’t know the current status. There have been times in the past where the shell would turn off the suid bit before proceeding. If you wanted it to work you had to force the realuid to 0 before calling system().

Oh! Do you have any reference? I know that this was (and probably still is) the case with shell scripts, but that is different story.