Automated ACL Check in shell script - linux

I'd like to get some ideas from you on how to implement that. Let me explain a little bit my problem:
Scenario:
We have a system that must have some especific ACLs set in order to run it. So, before running it would be great if I could run a sort of pre check in order to verify if everything was set correctly.
Goal:
Create a script that checks those ACLs before starting the system alerting in case one of them is wrong based in a list of files/folder and its ACLs.
Problems:
Since the getfacl result is not a simple return, the only way I found to do such checking was parsing the result and analising each piece of it, that not as elegant as I'd like it could be.
I doubt many of you had to do something ACLs check but for sure you guys can contribute to my cause :)
Thanks everybody in advance

How about using Python module pylibacl
>>> import posix1e
>>> acl1 = posix1e.ACL(file="file1.txt")
>>> print acl1
user::rw-
group::r--
other::r--

Since the getfacl result is not a simple return, the only way I found to do such checking was parsing the result and analising each piece of it, that not as elegant as I'd like it could be.
What exactly are you trying to do? If you're just comparing the result of calling getfacl to a desired ACL, it should be easy. For example, assuming that you have stored your desired ACL in a file named acl-i-want, you could do something like this:
getfacl /path > acl-i-have
if ! diff -q acl-i-have acl-i-want; then
echo "ACLs are different."
fi

Related

Unshare and newuidmap: update

I'm trying to create a process with its own namespace and then make a uid (and possibly gid) mapping. I'm following this question with this answer, but, as indicated in this recent comment, it no longer works.
Here's the skinny. First, you create a process in a new namespace with unshare:
unshare -U bash
And obtain the process it runs, with echo $$ or somesuch. You grab that PID and then, from another shell, you go:
newuidmap 12394 0 0 1
The answer, as indicated in the comment above, is:
newuidmap: uid range [0-1) -> [0-1) not allowed
In an update to the answer, Arks mentions:
it is something with settings in /etc/subuid and /etc/subguid files
I can't figure out, however, what they mean. Any idea?
Still don't understand why newuidmap does not work. But this article shows that writing to /proc/$$/uid_map does
echo '5 1000 1' > /proc/14671/uid_map
This is an one-time operation that can't be repeated, and in a single command, establishes the mapping for UIDs and GIDs.

Skipping Sendmail's Queue

I've set up Sendmail so that all messages are delivered to /dev/null instead of being actually stored anywhere else. I'm trying to reduce the number of unecessary disk writes and since those messages are essentially removed I want to, if possible, skip writing them to mqueue. Is there any way to do that?
The closest I could think of is mounting a nullfs filesystem on the mqueue directory, but I'd like a "cleaner" approach using sendmail only. Is this possible?
Thanks!
Most likely you choose wrong way to solve your problem but anyway:
You can select discard mailer for all recipients in check_rcpt (Local_check_rcpt) rule set. It will act as equivalent of DISCARD in access table.
Add the following lines to sendmil.mc file, generate new sendmail.cf file and restart or HUP sendmail daemon.
LOCAL_RULESETS
SLocal_check_rcpt
# PUT TAB (\t) BEFORE $# !!!
R$* $#discard $: discard

How can you hide passwords in command line arguments for a process in linux

There is quite a common issue in unix world, that is when you start a process with parameters, one of them being sensitive, other users can read it just by executing ps -ef. (For example mysql -u root -p secret_pw
Most frequent recommendation I found was simply not to do that, never run processes with sensitive parameters, instead pass these information other way.
However, I found that some processes have the ability to change the parameter line after they processed the parameters, looking for example like this in processes:
xfreerdp -decorations /w:1903 /h:1119 /kbd:0x00000409 /d:HCG /u:petr.bena /parent-window:54526138 /bpp:24 /audio-mode: /drive:media /media /network:lan /rfx /cert-ignore /clipboard /port:3389 /v:cz-bw47.hcg.homecredit.net /p:********
Note /p:*********** parameter where password was removed somehow.
How can I do that? Is it possible for a process in linux to alter the argument list they received? I assume that simply overwriting the char **args I get in main() function wouldn't do the trick. I suppose that maybe changing some files in /proc pseudofs might work?
"hiding" like this does not work. At the end of the day there is a time window where your password is perfectly visible so this is a total non-starter, even if it is not completely useless.
The way to go is to pass the password in an environment variable.

using and(&&) operator in for loop in linux

01) I am trying to use the && operator in a for loop as shown below in the script. However this does not seem to work. I was not able to see the error generated in the terminal window, since it closes as soon as it runs in to an error. Could someone please tell me what I'm doing wrong?
#!/bin/bash
cd ~/Documents/DTI/
#subj and subj1 contain folders which are located in the DTI directory
subj="ARN MT"
subj1="ARNpre1 ARNpre2"
for [[s in $subj] && [s1 in $subj1]]
02) And as you can see in my "subj1", the first two entries start with the letters ARN which means that they are sub directories of ARN(located in a different place.Not in ARN main directory). So I also want to run a command in which, if subj1 contains subj then it must perform a certain command.For this purpose I wrote the following,
if [[ ${s1} == *"${s}"* ]];then
would this be the right way to do such operation?
I would greatly appreciate any help.
Thank you in advance.
I think by for [[s in $subj] && [s1 in $subj1]] you mean this:
for s in $subj; do
for s1 in $subj1; do
# do something
done
done
By nesting the for loops you'll loop through every possible combination of s and s1, which sounds like what you're trying to do in part 1 of your question.
However, I can't make sense of what you're talking about in part 2, so I can't help you there.

Using a Chef recipe to append multiple lines to a config file

I'm trying to create a Chef recipe to append multiple lines (20-30) to a specific config file.
I'm aware the recommended pattern is to change entire config files rather than just appending to a file, but I dislike this approach for multiple reasons.
So far the only solution I found was to use a cookbook_file and then use a bash resource to do:
cat lines_to_append >> /path/configfile
Obviously this wouldn't work properly, as it'd append the file over and over, each time you run chef-client. I'd have to create a small bash script to check for a specific string first, and, if not found, append to the file.
But this seems to defeat the purpose of using Chef. There must be a better way.
One promising solution was the line cookbook from OpsCode Community. It aimed to solve this exact problem. Unfortunately the functionality is incomplete, buggy, and the code is just a quick hack. Far from being a solid solution.
Another option I evaluated was augeas. Seems pretty powerful, but it'd add yet-another layer of abstraction to the system. Overkill, in my case.
Given that this is one of the most obvious tasks for any sysadmin, is there any easy and beautiful solution with Chef that I'm not seeing?
EDIT: here's how I'm solving it so far:
cookbook_file "/tmp/parms_to_append.conf" do
source "parms_to_append.conf"
end
bash "append_to_config" do
user "root"
code <<-EOF
cat /tmp/parms_to_append.conf >> /etc/config
rm /tmp/parms_to_append.conf
EOF
not_if "grep -q MY_IDENTIFIER /etc/config"
end
It works, but not sure this is the recommended Chef pattern.
As you said yourself, the recommended Chef pattern is to manage the whole file.
If you're using Chef 11 you could probably make use of partials for what you're trying to achieve.
There's more info here and on this example cookbook.
As long as you have access to the original config template, just append <%= render "original_config.erb" %> to the top of your parms_to_append.conf template.
As said before, using templates and partials is common way of doing this, but chef allows appending files, and even changing(editing) file lines. Appendind is performed using following functions:
insert_line_after_match(regex, newline);
insert_line_if_no_match(regex, newline)
You may find and example here on stackoverflow, and the full documentation on rubydoc.info
Please use it with caution, and only when partials and templates are not appropriate.
I did something like this:
monit_overwrites/templates/default/monitrc.erb:
#---FLOWDOCK-START
set mail-format { from: monit#ourservice.com }
#---FLOWDOCK-END
In my recipe I did this:
monit_overwrites/recipes/default.rb:
execute "Clean up monitrc from earlier runs" do
user "root"
command "sed '/#---FLOWDOCK-START/,/#---FLOWDOCK-END/d' > /etc/monitrc"
end
template "/tmp/monitrc_append.conf" do
source "monitrc_append.erb"
end
execute "Setup monit to push notifications into flowdock" do
user "root"
command "cat /tmp/monitrc_append.conf >> /etc/monitrc"
end
execute "Remove monitrc_append" do
command "rm /tmp/monitrc_append.conf"
end
The easiest way to tackle this would be to create a string and pass it to content. Of course bash blocks work... but I think file resources are elegant.
lines = ""
File.open('input file') do |f|
f.lines.each do |line|
lines = lines + line + "\n"
end
end
file "file path" do
content line
end
Here is the example ruby block for inserting 2 new lines after match:
ruby_block "insert_lines" do
block do
file = Chef::Util::FileEdit.new("/etc/nginx/nginx.conf")
file.insert_line_after_match("worker_rlimit_nofile", "load_module 1")
file.insert_line_after_match("pid", "load_module 2")
file.write_file
end
end
insert_line_after_match searches for the regex/string and it will insert the value in after the match.

Resources