Linux - SecurityThis forum is for all security related questions.
Questions, tips, system compromises, firewalls, etc. are all included here.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
// ars.cpp by Adam Williams C(2010) Kinetic Software
//
// This is the main menu module for DAS 4.5, ported to C++ for binary compilation and code obfuscation.
// If you are reading this, and you are not me, shame on you for piracy.
//
// If you are me, then I apologize for what I am about to do to you. Courage.
#include <iostream>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <sstream>
#define water_is_wet true
#define tFileName_def "/tmp/TEMPoFILEo5345"
using namespace std; //Yeah yeah. Shoot me. I'm lazy.
int main()
{
const char *tFileName = tFileName_def; //Defined above
const string menuFileDefinition = "resources/menu.lst";
fstream menuFile;
fstream tempFile;
ostringstream dialogOut; // If string streams work the way I think they do, then I'm in love. It can't be true.
// Update 1 Hour later: ITS TWUE!! ITS TWUE!!
char labels[10], iChar = ' ';
short int i = 0, numEntries = 0, menuLength = 0, selection = -200, errCode = 0;
string commands[10], comments[10], dialogCommand = "";
char testChar = ' ';
system ("/usr/bin/setleds +num"); // Turns on Num Lock. Linux Console Init States piss me off.
menuFile.open( "/codex/source/resources/menu.lst", ios::in);
while (! menuFile.eof())
{
if(i < 10)
{
iChar = '1' + i; // Magic - Converts int to char
labels[i] = iChar;
getline (menuFile, comments[i]); // Retrieves Command description
getline (menuFile, commands[i++]);// Retrieves Command string
// They are stored in pairs in menuFile
}
else break;
}
i--;
menuFile.close();
numEntries = i;
labels[i] = 'Q';
comments[i] = "Exit";
commands[i] = "IC=EXIT";
// ^^^^^^^^^^^^^^^^ All of the above is initialization.
while (water_is_wet)
{
menuLength = numEntries + 10;
dialogOut.str(""); // Why isn't there a method that does these two lines?
dialogOut.clear(); // That would be much simpler.
dialogOut << "dialog --menu \"Welcome to DAS 4.5\\nPlease select an option:\" ";
dialogOut << menuLength << " 40 ";
dialogOut << (numEntries+1) << " "; // +1 to adjust for 0 start array
for(i=0; i <= numEntries; i++)
{
dialogOut << "\"" << labels[i] << "\" \"" << comments[i] << "\" ";
}
remove (tFileName);
dialogOut << " 2> " << tFileName;
dialogCommand = dialogOut.str();
errCode = system(dialogCommand.c_str());
if(( (errCode>>8) == 1) || ((errCode>>8) == -1)) // Dialog returns 1 for cancel button, -1 for escape
{
remove (tFileName);
system("clear");
return(0);
break;
}
tempFile.clear();
tempFile.open(tFileName, ios::in);
tempFile.get(testChar);
tempFile.close();
remove (tFileName);
selection = testChar;
if(selection == 81) // Check for 'Q' as returned char
{
remove (tFileName);
system("clear");
return(0);
break;
}
else
{
selection -= '1'; // Adjust for 0 start array
errCode = system(commands[selection].c_str());
if ((errCode>>8) == 126)
{
system("dialog --infobox \"You do not have sufficient priveledges to perform this task.\" 4 38");
system("sleep 2");
}
}
}
remove(tFileName); // make sure there's no ugly temp file left behind.
system("clear");
if(selection == 81)
{
return 0;
}
else
{
return 1;
}
}
This was the first time I had used string streams. I got a little excited.
*EDIT: Whoops. Forgot to add the menu.lst file. I'll have to do it in an hour. My boss is chasing me out the door to lunch.
Last edited by thndrchld; 12-29-2010 at 12:19 PM.
Reason: Changed quote tag to code tag
We still don't know if adam and brad have trouble getting permission to execute ars or if the permission problem comes from accessing an object during execution of ars.
Can you log on as adam and/or brad and run strace ars?
Code:
strace /codex/source/ars
That will show us if adam and brad are prohibited from running ars of if they can execute the file but get a permission problem during execution.
Looking at the code, one thing that comes to mind is the temporary file,
Code:
#define tFileName_def "/tmp/TEMPoFILEo5345"
Wouldn't it be better to use a unique random file name? In my ignorance I am inclined to believe that there must exist a standard function to create such a file name within the C++ libraries.
What are the permissions on the /tmp directory?
Are you sure that the temp file doesn't exist before trying to execute ars?
Nevertheless these kinds of issues should affect all of the users, not just adam and brad.
When adam and/or brad have /bin/bash as their login shell can they see and/or write to the files using the command line?
Last edited by stress_junkie; 12-29-2010 at 11:21 AM.
/tmp is set to 777. It actually hadn't occurred to me to use a random filename for the temp file. I'll implement that in my next update (when I get time). For the moment, further down the code there are remove(tFileName) statements all over the place. any possible exit to the program besides faults are preceded by deletion of the file. Also, just to be sure, i delete the file immediately after reading the data from it.
Just to test, I checked. The file doesn't exist currently, so that's not it.
Also, this occurred to me as I was driving to lunch. The other scripts in the folder besides ars also give the same exact error message with the name of the script substituted for "/codex/source/ars". The others are written in bash and perl, and don't access the same resources. They have their own configuration files to access in /codex/source/resources. I checked the folder. It is owned by root:recovery and has 750 permission.
I've never heard of strace. I'll try it here in a minute.
When /bin/bash is set to the login shell, they can see that the files exist, but cannot read or execute them. Unless they su to an account that can (which they shouldn't be able to do anyway - not in sudoers) they should never be able to write any file in /codex/source. /codex/accounts, however must be writable.
The last field is supposed to be the path to the user's login shell.
From man 5 passwd
Quote:
shell
The program to run at login (if empty, use /bin/sh). If set to a non-existing executable, the user will be unable to login through login(1).
Is /usr/scripts/ars a shell, in the way /bin/bash or /bin/csh is?
I have never heard of an ars shell.
If you don't know what the ars shell is either, you might want to try setting those user's login shells to /bin/bash log them all out, and then see if things improve.
The last field is supposed to be the path to the user's login shell.
From man 5 passwd
Is /usr/scripts/ars a shell, in the way /bin/bash or /bin/csh is?
I have never heard of an ars shell.
If you don't know what the ars shell is either, you might want to try setting those user's login shells to /bin/bash log them all out, and then see if things improve.
ars isn't a shell, per se; it's a menu system I wrote. It's worked for the last few years in various incarnations. It's just stopped working the day before yesterday for adam and brad. It still works for other users.
Setting the login shell to /bin/bash allows the user to log in, but puts then at a bash prompt, which I don't want. The shell entry of the passwd file is supposed to also be able to launch a login script, the termination of which logs the user out. In ars, one of the menu entries invokes /bin/bash to grant terminal access. Exiting the menu entirely, however, logs the user out.
Begin Recovery Operation
/usr/scripts/recover
Retrieve Data from CODEX
/usr/scripts/retrieve
Search for Specific Filetypes
/usr/scripts/search
Purge old accounts
/usr/scripts/purge
Update Catalog Files
/usr/scripts/updateCatalogs
View Ticket Journal
/usr/scripts/viewJournal
View or Print Logfile
/usr/scripts/viewLog
Add User
/usr/scripts/createUser
Start Terminal Session
/bin/bash
I changed the permissions on the less binary on my machine so that normal users are not allowed to run it. Then as a normal user I ran strace less <text-file>. I have permission to read the text file. The result of my test is virtually identical to the result of your test.
BUT, unfortunately that is not the cause of the problems as indicated by your next post.
Quote:
Originally Posted by thndrchld
When /bin/bash is set to the login shell, they can see that the files exist, but cannot read or execute them. Unless they su to an account that can (which they shouldn't be able to do anyway - not in sudoers) they should never be able to write any file in /codex/source. /codex/accounts, however must be writable.
As a side note any user account can use su to log on as any other user. The sudoers file is for controlling the use of the sudo utility/command.
I'm getting confused about what adam and brad are supposed to be able to do and what they actually can do.
adam and brad are in the same user groups as the others, plus adam and brad are in the purge user group. So adam and brad should be able to anything that the others can do plus adam and brad should be able to run the scripts owned by the purge user group. Yes?
Quote:
Originally Posted by tredegar
Sorry to butt in...
Don't be. This isn't a private conversation. Any help is appreciated.
Last edited by stress_junkie; 12-29-2010 at 12:47 PM.
Regarding the su thing - Right... Brain fart. I'm not quite sure what I was thinking, there.
Adam and Brad should be able to do everything the others users can, but they should also be able to run the purge script, which is owned by group 'purge'.
The problem is that NONE of the scripts are working for adam or brad, regardless of what group they are owned by. adam cannot run ars, recover, purge, createUser, or any of them. Brad has the same problem, except he shouldn't be able to run createUser or deleteUser regardless.
You said that this was working for all of the user accounts until the day before yesterday. Can you think of any changes to the system or to any user accounts that occurred two days ago? Did you reboot the system just before this broke?
I noticed that the home directory for all of the user accounts is /home/<username>. Do those directories exist for adam and brad? Are they and their contents owned by the proper user?
Last edited by stress_junkie; 12-29-2010 at 01:33 PM.
our /codex/source/ars is owned by user root, group recovery, and has mode -rwxr-x---. This means only the root user and the recovery group are allowed to read or run it. So, just add execute and read (since it's a script) for everybody:
Code:
sudo chmod o+rx /codex/source/ars
If you need to limit the access to the script, I recommed creating an additional group, say ars-users, and adding all allowed users to this group, and then allowing only ars-users to run ars:
where ars-admin is either some administrator user, or root.
I personally recommend using a special administrator user account for script maintenance, one not allowed to login at all.
This way you don't sudo as root, but as the administrator user (sudo -u scriptadmin ...). If the maintenance burden shifts to somebody else, you don't need to chown a lot of files; just make sure that new admin is allowed to sudo as scriptadmin.
Nominal Animal
Last edited by Nominal Animal; 03-21-2011 at 01:34 AM.
1. I introduced a new version of the ars binary. The only change in the new version is the following code:
Code:
errCode = system(commands[selection].c_str());
if ((errCode>>8) == 126)
{
system("dialog --infobox \"You do not have sufficient privileges to perform this task.\" 4 38");
system("sleep 2");
}
The previous version ignored the return code of system(commands[selection].c_str()). Now, it checks it to see if there was a permissions error, and displays a message if there was. Previously, it would just ignore the selection without notice to the user.
Before the previous version, a perl script sat in ars's current location. This script worked flawlessly, except for the fact that the menu items were coded into the script and not pulled from a configuration file.
2. The other change was when I noticed that permissions weren't set properly to disallow access to purge, createUser, and deleteUser. Before the change, permissions were 777 on everything, which they SHOULD NOT HAVE BEEN. After the change, they were 750.
Nominal Animal:
That's basically the way it's set up now. Anybody that should be able to access ars, should also be able to access the other scripts, with the exception of purge, createUser, and deleteUser. That's why recovery has group ownership of the files. They're owned by user root because I sudo cp'd (cpd? cped?) them in place and never bothered to change user ownership. They were previously owned by user dapsychous.
I don't want others to be able to access the scripts. Only users in the recovery group should have access.
----
The thing is, this isn't centered around ars. This problem occurs with all the scripts in this folder for Adam and Brad only. I don't think it could be a problem specifically with ars, or the other scripts would work.
Okay so the problem didn't show itself when the file permissions were too permissive. That means that the problem may have always existed. Darn.
The getfacl commands have shown that ACLs are not being used. We already knew that but confirmation helps create peace of mind. The only reason that I wanted to double check that is that this is so typical of the kinds of problems that ACLs can create.
Can adam or brad read the problematic scripts? Log on as adam and try to cat one of the scripts.
Code:
cat /codex/source/script-name
If yes then try to execute the same script with echo on as follows:
Code:
/bin/bash -v /codex/source/script-name
Make a note of which command tries to execute when you get the permission denied message. It may still just be when adam or brad tries to execute the script but I am hoping that it is some command inside the script that is causing the problem.
I tested with a script called recover. It is a bash shell script, but it's a beast, and a right pain in the ass to boot. If you like I can post the source, but it's a big, recursive monster.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.