UNIX equivalent of CreateProcessWithLogonW - unix

What I have: the login/password for a UNIX user (alice).
Who I am: some other UNIX user (bob).
What I need to do: start a process programmatically (foo) as the other user (alice).
What the end result should be: the process is running and displays alice as the owner if a "ps" is done. For purposes of privileges, acts as if alice started it.
Basically I need to write some code that does the equivalent of "su -c 'foo' - alice"
Ideally I don't want to have to set any special bits or permissions on the executable in question (foo).

I see only two possibilites to start a process as alice on UNIX/Linux from a process owned by bob that cannot setuid itself.
call a setuid program
communicate with an already running process that can start processes as alice

Never say never, but I think this is probably impossible in any unix-portable way. The setuid(2) call (and friends) succeeds only if the current uid is either the same as the target one (modulo some subtleties about effective and real uids) or if the current uid is 0 (ie, root). That is, you can't change from one non-root uid to another.
Having the password doesn't help. The password is used for the initial authentication to the system, whether it be via login, ssh, or some GUI login dialogue, but the password is the concern of those programs alone, and not of the system as such. Put another way, the kernel doesn't care about your password, and it's the kernel that you have to talk to if you want to change your uid.
That is, you're probably therefore obliged to consider indirect routes, such as the ones Peter G mentioned.
(Yes, some unixes may have a way of doing this, but that's platform-specific).
I know I'm not adding any positive advice here, only the possibly time-saving negative advice of 'nothing to see here; move right along...'

Related

Monitoring SaltStack

Is there anything out there to monitor SaltStack installations besides halite? I have it installed but it's not really what we are looking for.
It would be nice if we could have a web gui or even a daily email that showed the status of all the minions. I'm pretty handy with scripting but I don't know what to script.
Anybody have any ideas?
In case by monitoring you mean operating salt, you can try one of the following:
SaltStack Enterprise GUI
Foreman
SaltPad
Molten
Halite (DEPRECATED by SaltStack)
These GUI will allow you more than just knowing whether or not minions are alive. They will allow you to operate on them in the same manner you could with the salt client.
And in case by monitoring you mean just whether the salt master and salt minions are up and running, you can use a general-purpose monitoring solutions like:
Icinga
Naemon
Nagios
Shinken
Sensu
In fact, these tools can monitor different services on the hosts they know about. The host can be any machine that has an ip address and the service can be any resource that can be queried via the underlying OS. Example of host can be a server, router, printer... And example of service can be memory, disk, a process, ...
Not an absolute answer, but we're developing saltpad, which is a replacement and improvement of halite. One of its feature is to display the status of all your minions. You can give it a try: Saltpad Project page on Github
You might look into consul while it isn't specifically for SaltStack, I use it to monitor that salt-master and salt-minion are running on the hosts they should be.
Another simple test would be to run something like:
salt --output=json '*' test.ping
And compare between different runs. It's not amazing monitoring, but at least shows your minions are up and communicating with your master.
Another option might be to use the salt.runners.manage functions, which comes with a status function.
In order to print the status of all known salt minions you can run this on your salt master:
salt-run manage.status
salt-run manage.status tgt="webservers" expr_form="nodegroup"
I had to write my own. To my knowledge, there is nothing out there which will do this, and halite didn't work for what I needed.
If you know Python, it's fairly easy to write an application to monitor salt. For example, my app had a thread which refreshed the list of hosts from the salt keys from time to time, and a few threads that ran various commands against that list to verify they were up. The monitor threads updated a dictionary with a timestamp and success/fail for each host after they ran. It had a hacked together HTML display color coded to reflect the status of each node. Took me a about half a day to write it.
If you don't want to use Python, you could, painfully, do something similar to this inefficient, quick, untested hack using command line tools in bash.
minion_list=$(salt-key --out=txt|grep '^minions_pre:.*'|tr ',' ' ') # You'
for minion in ${minion_list}; do
salt "${minion}" test.ping
if [ $? -ne 0 ]; then
echo "${minion} is down."
fi
done
It would be easy enough to modify to write file or send an alert.
halite was depreciated in favour of paid ui version, sad, but true - still saltstack does the job. I'd just guess your best monitoring will be the one you can write yourself, happily there's a salt-api project (which I believe was part of halite, not sure about this), I'd recommend you to use this one with tornado as it's better than cherry version.
So if you want nice interface you might want to work with api once you set it up... when setting up tornado make sure you're ok with authentication (i had some trouble in here), here's how you can check it:
Using Postman/Curl/whatever:
check if api is alive:
- no post data (just see if api is alive)
- get request http://masterip:8000/
login (you'll need to take token returned from here to do most operations):
- post to http://masterip:8000/login
- (x-www-form-urlencoded data in postman), raw:
username:yourUsername
password:yourPassword
eauth:pam
im using pam so I have a user with yourUsername and yourPassword added on my master server (as a regular user, that's how pam's working)
get minions, http://masterip:8000/minions (you'll need to post token from login operation),
get all jobs, http://masterip:8000/jobs (you'll n need to post token from login operation),
So basically if you want to do anything with saltstack monitoring just play with that salt-api & get what you want, saltstack has output formatters so you could get all data even as a json (if your frontend is javascript like) - it lets you run cmd's or whatever you want and the monitoring is left to you (unless you switch from the community to pro versions) or unless you want to use mentioned saltpad (which, sorry guys, have been last updated a year ago according to repo).
btw. you might need to change that 8000 port to something else depending on version of saltstack/tornado/config.
Basically if you want to have an output where you can check the status of all the minions then you can run a command like
salt '*' test.ping
salt --output=json '*' test.ping #To get output in Json Format
salt manage.up # Returns all minions status
Or else if you want to visualize the same with a Dashboard then you can see some of the available options like Foreman, SaltPad etc.

UNIX - Stopping a custom service

I created a client-server application and now I would like to deploy it.
While development process I started the server on a terminal and when I wanted to stop it I just had to type "Ctrl-C".
Now want to be able to start it in background and stop it when I want by just typing:
/etc/init.d/my_service {stop|stop}
I know how to do an initscript, but the problem is how to actually stop the process ?
I first thought to retrieve the PID with something like:
ps aux | grep "my_service"
Then I found a better idea, still with the PID: Storing it on a file in order to retrieve it when trying to stop the service.
Definitely too dirty and unsafe, I eventually thought about using sockets to enable the "stop" process to tell the actual process to shut down.
I would like to know how this is usually done ? Or rather what is the best way to do it ?
I checked some of the files in the init.d and some of them use PID files but with a particular command "start-stop-daemon". I am a bit suspicious about this method which seems unsafe to me.
If you have a utility like start-stop-daemon available, use it.
start-stop-daemon is flexible and can use 4 different methods to find the process ID of the running service. It uses this information (1) to avoid starting a second copy of the same service when starting, and (2) to determine which process ID to kill when stopping the service.
--pidfile: Check whether a process has created the file pid-file.
--exec: Check for processes that are instances of this executable
--name: Check for processes with the name process-name
--user: Check for processes owned by the user specified by username or uid.
The best one to use in general is probably --pidfile. The others are mainly intended to be used in case the service does not create a PID file. --exec has the disadvantage that you cannot distinguish between two different services implemented by the same program (i.e. two copies of the same service). This disadvantage would typically apply to --name also, and, additionally, --name has a chance of matching an unrelated process that happens to share the same name. --user might be useful if your service runs under a dedicated user ID which is used by nothing else. So use --pidfile if you can.
For extra safety, the options can be combined. For example, you can use --pidfile and --exec together. This way, you can identify the process using the PID file, but don't trust it if the PID found in the PID file belongs to a process that is using the wrong executable (it's a stale/invalid PID file).
I have used the option names provided by start-stop-daemon to discuss the different possibilities, but you need not use start-stop-daemon: the discussion applies just as well if you use another utility or do the matching manually.

have R halt the EC2 machine it's running on

I have a few work flows where I would like R to halt the Linux machine it's running on after completion of a script. I can think of two similar ways to do this:
run R as root and then call system("halt")
run R from a root shell script (could run the R script as any user) then have the shell script run halt after the R bit completes.
Are there other easy ways of doing this?
The use case here is for scripts running on AWS where I would like the instance to stop after script completion so that I don't get charged for machine time post job run. My instance I use for data analysis is an EBS backed instance so I don't want to terminate it, simply suspend. Issuing a halt command from inside the instance is the same effect as a stop/suspend from AWS console.
I'm impressed that works. (For anyone else surprised that an instance can stop itself, see notes 1 & 2.)
You can also try "sudo halt", as you wouldn't need to run as a root user, as long as the user account running R is capable of running sudo. This is pretty common on a lot of AMIs on EC2.
Be careful about what constitutes an assumption of R quitting - believe it or not, one can crash R. It may be better to have a separate script that watches the R pid and, once that PID is no longer active, terminates the instance. Doing this command inside of R means that if R crashes, it never reaches the call to halt. If you call it from within another script, that can be dangerous, too. If you know Linux well, what you're looking for is the PID from starting R, which you can pass to another script that checks ps, say every 1 second, and then terminates the instance once the PID is no longer running.
I think a better solution is to use the EC2 API tools (see: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ for documentation) to terminate OR stop instances. There's a difference between the two of these, and it matters if your instance is EBS backed or S3 backed. You needn't run as root in order to terminate the instance - the fact that you have the private key and certificate shows Amazon that you're the BOSS, way above the hoi polloi who merely have root access on your instance.
Because these credentials can be used for mischief, be careful about running API tools from a given server, you'll need your certificate and private key on the server. That's a bad idea in the event that you have a security problem. It would be better to message to a master server and have it shut down the instance. If you have messaging set up in any way between instances, this can do all the work for you.
Note 1: Eric Hammond reports that the halt will only suspend an EBS instance, so you still have storage fees. If you happen to start a lot of such instances, this can clutter things up. Your original question seems unclear about whether you mean to terminate or stop an instance. He has other good advice on this page
Note 2: A short thread on the EC2 developers forum gives advice for Linux & Windows users.
Note 3: EBS instances are billed for partial hours, even when restarted. (See this thread from the developer forum.) Having an auto-suspend close to the hour mark can be useful, assuming the R process isn't working, in case one might re-task that instance (i.e. to save on not restarting). Other useful tools to consider: setTimeLimit and setSessionTimeLimit, and various checkpointing tools (I have a Q that mentions a couple). Using an auto-kill is useful if one has potentially badly behaved code.
Note 4: I recently learned of the shutdown command in package fun. This is multi-platform. See this blog post for commentary, and code is here. Dangerous stuff, but it could be useful if you want to adapt to Windows. I haven't tried it, though.
Update 1. Three more ideas:
You could use .Last() and runLast = TRUE for q() and quit(), which could shut down the instance.
If using littler or a script that invokes the script via Rscript, the same command line functions could be used.
My favorite package of today, tcltk2 has a neat timer mechanism, called tclTaskSchedule() that can be used to schedule the execution of an expression. You could then go crazy with the execution of stuff just before a hourly interval has elapsed.
system("echo 'rootpassword' | sudo halt")
However, the downside is having your root password in plain text in the script.
AFAIK those ways you mentioned are the only ones. In any case the script will have to run as root to be able to shut down the machine (if you find a way to do it without root that's possibly an exploit). You ask for an easier way but system("halt") is just an additional line at the end of your script.
sudo is an option -- it allows you to run certain commands without prompting for any password. Just put something like this in /etc/sudoers
<username> ALL=(ALL) PASSWD: ALL, NOPASSWD: /sbin/halt
(of course replacing with the name of user running R) and system('sudo halt') should just work.

Is it possible for a UNIX/Linux shell script to 'exit' and log out the current user?

We're having a strange issue here. Unfortunately I'm not at liberty to post the code here because it belongs to the vendor, but hopefully can provide enough info so that isn't necessary.
Much could be explained if someone here could definitively say whether or not it is possible for 'bob' to execute "some_script.sh", and have it exit out of his su'd session MID-WAY and have the remainder of the script continue as user 'pete' (who originally su'd to impersonate 'bob')
I'm fairly certain that this is not possible, but is there anyone out there that knows otherwise?
Things to keep in mind:
scriptA.sh executes multiple other processes (serially) which make changes to a database
lets assume that these are 01.sql through to 10.sql.
It does this by executing 'sqlplus' with appropriate arguments.
The 'sqlplus' binary is available to user 'bob', but NOT user 'pete'.
User pete is currently su'd into user 'bob', because pete doesn't have sqlplus on his PATH.
The output we saw in the script/database suggested that the '01.sql' was executed successfully, but not the others - they failed with a 'sqlplus command not found' error.
Cheers,
From the information you've given, "No. It is not possible."
If user 'pete' su's to 'bob', he creates a new shell as 'bob'. Any processes started from that new shell are run as 'bob'. Any script, if run as 'bob', cannot change it's user/UID to 'pete'. Any processes started as 'bob' cannot change their user/UID (absent setuid bit on the executable).
It's far more likely that part of the script is modifying the shell environment and changing its PATH or some other error within the script.
Using a script to attempt to switch UIDs is doomed to failure. A permissions system that requires shared logins is – by definition – insecure.
Use the AIX permissions system the way it was intended. If you need bob's credentials to perform a task then have a program that Sandipan can execute which will elevate to bob permissions for only that which needs bob's credentials.
This is the Principle of Least Privilege and is how to handle the job. Shared passwords are a bad hack that encourages worse hacks.

Initiate an outgoing call with Asterisk

I have a database where one entry is structured like so:
number_to_call date file_to_play
Using asterisk, I need to do the following:
1. Check the database daily.
2. If date matches that of today's, then initiate call on number.
3. Once phone has been picked up, play file_to_play.
Some general pointers on how I even begin to do this would be great.
Most of the applications that I have written so far have worked on incoming calls. I have the following questions:
1. How do I write a "daemon" that will check the database? Asterisk should have both user and group privileges for it to execute properly. How do I do this?
2. Can I initiate an outgoing call from outside of the asterisk dialplan?
The calls are being made to a PSTN/mobile number.
You can Write any script Which can check DB on daily basis and once it maches the date range you can initiate a call using .call files.
Please study asterisk auto-dial out from voip-info.org - I think you can understand better then.
You can run your script for same user as asterisk runs there is also one more method to initiate call from linux which we can call Originate CLI command which can also refer to http://voip-info.org/.
In general it is not a great idea to write your own dialer, unless your volume is very very low. Where I work, we started rolling our own but at the end went with a commercial solution that handled most of the logic. There are a number of commercial and free solutions out there, so don't reinvent the wheel.
See my answer to https://stackoverflow.com/questions/11666755/outbound-dialer-using-asterisk/14589901#14589901 for why it is not a good idea to roll your own.

Resources