LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   There has *got* to be a better way to do this (https://www.linuxquestions.org/questions/linux-newbie-8/there-has-%2Agot%2A-to-be-a-better-way-to-do-this-664898/)

davidstvz 08-23-2008 04:25 PM

There has *got* to be a better way to do this
 
This is what I need, ultimately:

I need a user (a student) to be able to copy their homework into a grader's directory. Simple. Except the student can't have ordinary access to the grader directory or they can look at other peoples' homework.

This is how it used to be done:

This used to be done by using the SUID bit on a script. However, that doesn't work in a modern Linux kernel because SUID is now ignored on scripts.

Here is where I am now:

Absent anyway to use a script (I was unable to configure the sudoer file successfully) or some other trickery, I am now trying to write a c or c++ program to replace the script (because a binary can use the SUID bit).

However, I have to do this without use of the system() function in the C program because whenever I call that function to run something (script or binary), it runs with the student's rights not the graders despite being called from a program running with the grader's privileges.

There has got to be a better way. As it stands now, I'm having to write my own little versions of cp and rm within this c program (among other things) to make up for my inability to access basic shell functions. This is incredibly time consuming, annoying and prone to error.

If anyone has any ideas for solving this problem, please help. I'm dying here.

matthewg42 08-23-2008 04:52 PM

How about getting the students to email the tutor their files?

davidstvz 08-23-2008 04:56 PM

:)

Unfortunately I'm new here and this is how they're used to doing it. Besides the old server is still running. If I can't get the new server running "properly" (i.e. superficially like the old one) then everyone will want to use the old server. That will make me look very bad I think.

Besides there are some good uses to this system.

AceofSpades19 08-23-2008 05:07 PM

Quote:

Originally Posted by davidstvz (Post 3257387)
:)

Unfortunately I'm new here and this is how they're used to doing it. Besides the old server is still running. If I can't get the new server running "properly" (i.e. superficially like the old one) then everyone will want to use the old server. That will make me look very bad I think.

Besides there are some good uses to this system.

I don't like just because everyone is used to one way we can never ever change argument. Its like saying everyone is used to windows 3.1 so we can't upgrade to windows xp. Things have to change eventually

matthewg42 08-23-2008 05:15 PM

You can use sudo to run a script with escalated permissions. You can replace the original SUID script with one which calls the original script with sudo. You would then need to set up the /etc/sudoers file to provide the necessary privileges.

Be aware of the reasons SUID scripts were stopped - environment attacks and so on are very hard to guard against with scripts.

A good summary of some of the problems with SUID scripts can be found in section 7 of the secure programming howto.

btmiller 08-23-2008 05:18 PM

Here's one way... Have the directory owned by the grader and set permissions on it to 1733 (drwx-wx-wt). This way students can copy files into the directory, but cannot list its contents. They can, however, read any file in it so long as they know its name. To prevent this, you can ask students to chmod the files to make them not readable by other students (you could make the directory's GID a group that only graders are in and chmod g+s the directory to ensure any files placed within it have that group ID; students would still have to manually remove read permission from other, though).

Can you examine the old server to figure out how things are set up on it?

davidstvz 08-23-2008 05:30 PM

Quote:

Originally Posted by btmiller (Post 3257406)
Here's one way... Have the directory owned by the grader and set permissions on it to 1733 (drwx-wx-wt). This way students can copy files into the directory, but cannot list its contents. They can, however, read any file in it so long as they know its name. To prevent this, you can ask students to chmod the files to make them not readable by other students (you could make the directory's GID a group that only graders are in and chmod g+s the directory to ensure any files placed within it have that group ID; students would still have to manually remove read permission from other, though).

Can you examine the old server to figure out how things are set up on it?

hmmmm

There may be some issues here, but let me think about this.

using drwx-wx---

The students could write into that folder because write privileges are enabled for their group (the class they are in). Then they could chmod the file so that only they have any kind of access to it. Then they could chown it to the grader so that the grader owns it and from then on it ought to be protected and unreadable.

That is deficient in one way from the previous system. Once those files are in place, they are stuck there unless the grader deletes them manually. The student used to be able to resubmit their homework and it would copy over the old homework (if they did this after the deadline, then it would be considered late). This way, they can only submit each assignment once. This is a good position of last resort. I think for the moment I will continue with the C++ program I'm writing.

On second thought, maybe I'll do this and write a simple program to "cancel" a homework submission (at which point the student could resubmit with the original script).

davidstvz 08-23-2008 05:32 PM

Quote:

Originally Posted by matthewg42 (Post 3257401)
You can use sudo to run a script with escalated permissions. You can replace the original SUID script with one which calls the original script with sudo. You would then need to set up the /etc/sudoers file to provide the necessary privileges.

Be aware of the reasons SUID scripts were stopped - environment attacks and so on are very hard to guard against with scripts.

A good summary of some of the problems with SUID scripts can be found in section 7 of the secure programming howto.

I would love to use SUDO and just run the old script. So far I've been completely unable to do that however.

Could you possibly show me exactly how to set up the sudoer file, the permissions and anything else required? I tried this yesterday for hours and failed to get it working. The old script is a two part script. The first part runs with student permissions, the second part used to run using SUID with grader permissions (and was called from within the first script with an env_variable as an argument).

billymayday 08-23-2008 05:59 PM

David, I didn't read the whole chain of thought here, but did read your OP.

How about if you created a grading directory in each user's home directory, let's say /home/user/grading

Run a cron job that scans through each grading directory with a loop, say every 30 minutes, and simply copies the files to the grader's own directory.

Doesn't need any fancy permissioning, just needs the cron job to have sufficient permissions.

pinniped 08-23-2008 06:17 PM

You can use the file alteration monitoring scheme to detect a change in the directory and do a chown + chmod of all files which are not open. Alternatively, have the daemon do a chown+chmod then move the file to another directory; that way you don't do unnecessary chown/chmods.

davidstvz 08-23-2008 06:28 PM

That would definitely be a whole different way of doing things. It could work. However, I think I will stick with what I've got as I'm almost done and I need to finish this before Monday (ideally, if not sooner... Saints are playing in 30 minutes!)

Thanks for all the ideas everyone. I really appreciate it. Looks like a simple alteration to the permissions scheme is going to save the day for now.

Mr. C. 08-23-2008 06:41 PM

Add this to your /etc/sudoers file, tailoring to your needs:
Code:

Cmnd_Alias      GRADEPROGS = /full/path/to/submission_prog, /full/path/to/other_prog
Runas_Alias      GRADEUSER  = grader
%students        ALL = (GRADEUSER) NOPASSWD: GRADEPROGS

* Change students to the group in which all students are members.
* Change the Cmnd_Alias paths to a comma-separated list of full path names to your submission/deletion program(s).
* Change grader to the grader's group.

Students then submit as:

Code:

sudo -u grader /full/path/to/submission_prog args.

Tinkster 08-23-2008 06:42 PM

Are there any conventions around naming of the home-work
files, could you conceivably create a sub-directory per
student under a file-structure owned by the grader?

ls -l /home
drwx--x--x 5 grader users 184 2008-08-24 09:46 grader/

ls -l /home/grader
ls -ltr
total 0
drwxrws--- 2 stu3 grader 48 2008-08-24 09:46 stu3/
drwxrws--- 2 stu2 grader 48 2008-08-24 09:46 stu2/
drwxrws--- 2 stu1 grader 112 2008-08-24 09:49 stu1/


With those perms the stus can all write to their own
sub-directory, can't access each others, and the grader
can get to all of them. With the sticky bit set the
files under stuX will be group owner by grader.

But maybe I still didn't fully understand what you're
trying to achieve.



Cheers,
Tink

matthewg42 08-23-2008 06:42 PM

Using sudo...

Add all the students who will submit work to the group "students", or something like it. If it doesn't already exist, add it like this. Lets assume you have students bob and conny:
Code:

groupadd students
usermod -aG students bob
usermod -aG students conny

You also need a graders group - those who can read the submitted work. Lets say the users stang and filo are graders:
Code:

groupadd graders
usermod -aG graders stang
usermod -aG graders filo

You now need to allow students to call some script using sudo. For this, use the visudo command to add a line to the /etc/sudoers file (do not edit the file directly)
Code:

%students ALL = (ALL) /usr/local/bin/submit_work
You also need a folder where the work will be saved until graders take it work marking:
Code:

mkdir -p /var/local/submitted_work
chown nobody:graders /var/local/submitted_work
chmod 070 /var/local/submitted_work

The script /usr/local/bin/submit_work would look something like this:
Code:

#!/bin/bash

PATH="/bin:/usr/bin"
export PATH

grade_dir="/var/local/submitted_work"

submission="${1?ERROR - you should specify a file to submit}"

if [ ! -r "$submission" ]; then
        echo "ERROR - submission \"$submission\" is not readable."
        ls -l "$submission"
        exit 2
fi

submission_base="${submission##*/}"

if [ -a "$grade_dir/$submission_base" ]; then
        if [ $(stat --format=%U "$grade_dir/$submission_base") = "$SUDO_USER" ]; then
                echo "You previously submitted a file with the name \"$submission_base\""
                echo "You may overwrite it if you wish, but if you do"
                echo "you will not be able to recover the old version:"
                ls -l "$grade_dir/$submission_base"
                echo ""
                read -p "over-write $grade_dir/$submission_base? (y/N) " overwrite
                if [ "$overwrite" = "y" ]; then
                        echo "OK, I am overwriting the old version"
                else
                        echo "NOT overwriting the old version"
                        exit 3
                fi
        else
                echo "Someone else has already submitted \"$submission_base\""
                echo "Rename your file and try again."
                exit 4
        fi
fi

cp -f "$submission" "$grade_dir/" &&
        chown $SUDO_USER:graders "$grade_dir/$submission_base" &&
        chmod 460 "$grade_dir/$submission_base" &&
        ls -l "$grade_dir/$submission_base" &&
        echo "$submission accepted, thanks" ||
        echo "Something went wrong - you should try submitting again."

The script can be owned by root and with permission so that only root can execute/read/write it:
Code:

chown root:root /usr/local/bin/submit_work
chmod 700 /usr/local/bin/submit_work

Students would submit work like this:
Code:

sudo /usr/local/bin/submit_work file_to_submit
Users will be prompted for their own passwords when they submit work. This will prevent terminal hijack problems. If you want them to be able to do the command with no password, you would modify the sudo line to look like this:
Code:

%students ALL = NOPASSWD: /usr/local/bin/submit_work
This is a very simplistic scheme which would require submitted work files to assume some sort of naming convention to avoid conflicts - perhaps something like "username-assignment_number-attemptnumber". A more realistic way to do it would be to have sub-directories per user and have their files go into those directory names. It's up to you of course.

matthewg42 08-23-2008 06:50 PM

I'd like to add that the script there is really not programmed defensively. The only advantage over an suid script is that the people who are able to run it cannot look inside it to see what is happening, at least not directly (maybe they can trick it into printing itself).

Also, all graders are implicitly trusted not to mess with the student's files in a malicious way. There is no mechanism for the students to show that what has been marked is what they submitted. You could add some sort of signing or checksumming scheme for that I guess, where the student gets a sort of receipt which can be checked against what has been marked. That's a bit sinister though if you ask me - if the student cannot trust the grader, he/she is screwed either way.


All times are GMT -5. The time now is 09:34 AM.