Added invalid character exercise

This commit is contained in:
Ezri Brimhall 2024-10-06 18:39:41 -06:00
parent 6d9b5c4f8a
commit 3e341193d9
4 changed files with 2032 additions and 2005 deletions

17
invalid-char/README.md Normal file
View File

@ -0,0 +1,17 @@
## Remove an Invalid Character
The `^M` character is the carriage return character, and is the "CR" part of the CRLF line ending scheme used by Windows systems. A Linux system might encounter this when a file was created on a Windows computer and then transferred.
This task can be trivially completed using the `sed` command. In most Linux shells (including `bash`), control-V will allow you to enter control characters by following it with the control-key combination used to render it. In this case, pressing `C-v C-m` (control-V followed by control-M) will insert a `^M` token on the command line that will be replaced with the carriage return character when the command is run. It doesn't actually insert that character directly, as that would cause the cursor to return to the beginning of the line, which is obviously undesireable.
The command to run is this:
`sed -i 's/^M//g' /path/to/file`
where `^M` is the token inserted as stated above, rather than the literal characters `^` and `M`.
Another option would be to use `\\r`, the more traditional escape sequence for the carriage return character. However, escape sequences like this do not work in single-quoted strings in Bash, so to use this, you'd have to do the following instead:
`sed -i "s/\\r//g /path/to/file`
I tend to avoid using double-quoted strings for `sed` commands, as generally you'd want the `\\` chracter available for regex tokens, and having to escape it every time you use it is annoying, hence why I'd prefer the first command in this circumstance.

File diff suppressed because it is too large Load Diff

10
user-report/README.md Normal file
View File

@ -0,0 +1,10 @@
## Report Users with UID >= 1000
I decided to take a more complex approach with this task than would be necessary on a "standard" Linux installation to make the script more robust. It still has some tweaks that would need to be made on a University domain-joined computer (namely, checking the `lastlog` command and only printing users who have actually logged in, depending on the purpose of the report, since otherwise it would include _all_ accounts, as LDAP providers usually handle authorization independently of user enumeration and authentication). However, for smaller lists of centralized users, or for a system that makes heavy use of ephemeral users managed by `systemd`, this script will work.
I did this mainly because I use centralized authentication on my personal computers (mainly for synchronization of user IDs for NFS reasons), so I wanted to make sure I didn't provide a script that wouldn't even function on my own computers. It is, admittedly, less valuable to parse `getent passwd` enumeration when working with a large number of users in the central auth server.
However, what I see as the main purpose of a report like this -- getting a list of people who can log into a server -- would be better accomplished by checking the LDAP settings on said server and doing a manual LDAP search based on those settings. That way, you wouldn't have to filter out all the users that are not allowed to log in (and will be blocked at the authorization stage by the PAM `account` LDAP module) but can still be resolved.
As for some design decisions I made:
- I use `awk` to do the filtering, rather than a shell `if` statement, because I'm already using it to format the output. The `cut` command would work for extracting the fields, but can't format the output in one go like `awk` can.

View File

@ -18,9 +18,9 @@
# $1: username
# $3: uid
# $7: shell
if which getent &>/dev/null; then
getent passwd | sort | uniq | awk -F: '{if ($3 >= 1000 && $1 != "nobody") print "User: " $1 ", UID: " $3 ", Shell: " $7}'
else
echo "getent not found, falling back to /etc/passwd" >&2
awk -F: '{if ($3 >= 1000 && $1 != "nobody") print "User: " $1 ", UID: " $3 ", Shell: " $7}' /etc/passwd
fi
getent passwd | sort -t: -k3 -n | uniq | grep -v '^nobody:' | awk -F: '
$3 >= 1000 {
print $1 " (" $3 "): " $7
}
'