===================== CST8129 Bonus Project (Lab #12) ===================== -IAN! idallen@ncf.ca Due: in-person demo (only) due before 2pm Tuesday Dec 10. (lab or office demo only - no hand in - no email) Marks: up to 5% Late penalty: 100% after due date and time Purpose: practice writing real shell scripts for data mining Demo procedure: I will accept in-person demos during scheduled lab hours, or in my office (by appointment) until the due date. If you want to demo in my office, arrange it with me first. See the course announcements news group for my additional office hours this coming week. You can just "drop by" for a demo (if I'm in); but, students with an arranged appointment have first priority. You can demo part (even a very small part) of the script for part marks. ---------------------------------------------------------------- Write the following executable script named "50_group_lister.sh" ---------------------------------------------------------------- Follow the usual script_checklist.txt guidelines. Purpose: This script lists all the Unix groups to which a userid belongs. It gets the login group from the password file as well as any other groups found in the system groups file. Input: Syntax: $0 [userid] Accept an optional single userid argument on the command line. Prompt for and read the userid if it is missing. If the userid is empty, default to use the userid of the current user. Display the userid in a DEBUG message (see sample output, below). Initialization: If the file ~alleni/cst/lab12exercise/passwd is readable and not empty, use that as the name of the passwd file; if not, use the system passwd file /etc/passwd as the name of the passwd file. Display the name of the passwd file you are using in a DEBUG message. If the file ~alleni/cst/lab12exercise/group is readable and not empty, use that as the name of the group file; if not, use the system group file /etc/group as the name of the group file. Display the name of the group file you are using in a DEBUG message. Processing: Look up the userid in the first field of the passwd file (exact match only) and extract and save the user's numeric login groupid. (RTFM "man 5 passwd"; see also Appendix C p.747-748 to get the shell quoting correct.) Print an error and exit non-zero if nothing is found and saved for the given userid. Display the saved login groupid in a DEBUG message. Extract and save the real name field (GECOS field) from the passwd file. This field may be empty; that is not an error. Display the saved real name in a DEBUG message. Fix up the user's real name: If the userid ends in four or more adjacent digits, reverse order of the first and last blank-separated names in the saved name variable. (Students in the Linux Lab have their names loaded in backwards, with last name first! Swap the two parts of the the name so the student names read correctly with first name first.) If the userid doesn't end in four or more adjacent digits, just leave the name exactly as it is found in the GECOS field; no change is needed. If you fixed the name, display the fixed name in a DEBUG message. Look up the saved numeric login groupid in the group file (exact match only) and extract and save the alphabetic group name of this group. (RTFM "man 5 group") If nothing is found and saved for the given numeric groupid, display an error message and set the saved alphabetic group name to be "UNKNOWN". Display the groupid and saved alphabetic group name in a DEBUG message. Process the group file looking for the userid located anywhere in the user_list field of the line. If the userid is found anywhere in the user_list field, output the alphabetic group name of that line. (i.e. Extract and output the alphabetic group names of which this userid is a member.) You may use the oddball "word" delimiter regular expression characters here, to make the userid matching more exact; however, doing so will make your script fail on most other versions of Unix. (Other Unix versions do not support the oddball regular expression metacharacters. Avoid them.) Save all the output (the alphabetic group names found) in a variable. The command line you use to extract this group information may produce its output separated by newlines. Make sure the list of group names has any embedded newline characters translated to spaces when you save the output of the command. (We don't want newlines in the list.) Display the groupid and alphabetic group name(s) in a DEBUG message. Output: Output the following saved information in a nice format: - the userid - the full name - the numeric group id (from the passwd file) - the name of the group corresponding to the numeric group id - the list of the other groups to which the userid belongs Sample test output: I added extra debugging messages to my version of the script, so that I could see exactly what was happening. You can do this, too. *** $ ./50_group_lister.sh daemon DEBUG using passwd file '/home/alleni/cst/lab12exercise/passwd' DEBUG using group file '/home/alleni/cst/lab12exercise/group' DEBUG looking up 'daemon' in '/home/alleni/cst/lab12exercise/passwd' DEBUG userid 'daemon' has group '2' DEBUG userid 'daemon' has full name 'daemon' DEBUG looking up group ID '2' in file '/home/alleni/cst/lab12exercise/group' DEBUG groupid '2' has name 'daemon' DEBUG looking up 'daemon' in user lists in file '/home/alleni/cst/lab12exercise/group' DEBUG userid 'daemon' is also in groups 'bin daemon adm lp ' Userid: daemon Full Name: daemon Login group name: daemon Login group id: 2 Other groups: bin daemon adm lp *** $ ./50_group_lister.sh vize0001 DEBUG using passwd file '/home/alleni/cst/lab12exercise/passwd' DEBUG using group file '/home/alleni/cst/lab12exercise/group' DEBUG looking up 'vize0001' in '/home/alleni/cst/lab12exercise/passwd' DEBUG userid 'vize0001' has group '503' DEBUG userid 'vize0001' has full name 'Vizena Michelle' DEBUG reversed student name to be 'Michelle Vizena' DEBUG looking up group ID '503' in file '/home/alleni/cst/lab12exercise/group' DEBUG groupid '503' has name 'student' DEBUG looking up 'vize0001' in user lists in file '/home/alleni/cst/lab12exercise/group' DEBUG userid 'vize0001' is also in groups '' Userid: vize0001 Full Name: Michelle Vizena Login group name: student Login group id: 503 Other groups: *** $ ./50_group_lister.sh alleni DEBUG using passwd file '/home/alleni/cst/lab12exercise/passwd' DEBUG using group file '/home/alleni/cst/lab12exercise/group' DEBUG looking up 'alleni' in '/home/alleni/cst/lab12exercise/passwd' DEBUG userid 'alleni' has group '619' DEBUG userid 'alleni' has full name 'Ian Allen' DEBUG looking up group ID '619' in file '/home/alleni/cst/lab12exercise/group' DEBUG groupid '619' has name 'alleni' DEBUG looking up 'alleni' in user lists in file '/home/alleni/cst/lab12exercise/group' DEBUG userid 'alleni' is also in groups '' Userid: alleni Full Name: Ian Allen Login group name: alleni Login group id: 619 Other groups: *** $ ./50_group_lister.sh DEBUG using passwd file '/home/alleni/cst/lab12exercise/passwd' DEBUG using group file '/home/alleni/cst/lab12exercise/group' Enter the userid: <== blank line entered - uses my current userid as default DEBUG looking up 'alleni' in '/home/alleni/cst/lab12exercise/passwd' DEBUG userid 'alleni' has group '619' DEBUG userid 'alleni' has full name 'Ian Allen' DEBUG looking up group ID '619' in file '/home/alleni/cst/lab12exercise/group' DEBUG groupid '619' has name 'alleni' DEBUG looking up 'alleni' in user lists in file '/home/alleni/cst/lab12exercise/group' DEBUG userid 'alleni' is also in groups '' Userid: alleni Full Name: Ian Allen Login group name: alleni Login group id: 619 Other groups: *** $ ./50_group_lister.sh foobar DEBUG using passwd file '/home/alleni/cst/lab12exercise/passwd' DEBUG using group file '/home/alleni/cst/lab12exercise/group' DEBUG looking up 'foobar' in '/home/alleni/cst/lab12exercise/passwd' ./50_group_lister.sh: Cannot find group ID for 'foobar' in file '/home/alleni/cst/lab12exercise/passwd' *** $ ./50_group_lister.sh a b c DEBUG using passwd file '/home/alleni/cst/lab12exercise/passwd' DEBUG using group file '/home/alleni/cst/lab12exercise/group' ./50_group_lister.sh: expecting one userid, you gave 3 (a b c) Warning: We have not fully bullet-proofed our script to bad input! Of course, we quote all our variables to protect them from the shell; but, we are using other programs that also have input syntax limitations. Some inputs to this program may cause those other programs to misbehave and abort with error messages, for example: *** $ ./50_group_lister.sh '"' DEBUG using passwd file '/home/alleni/cst/lab12exercise/passwd' DEBUG using group file '/home/alleni/cst/lab12exercise/group' DEBUG looking up '"' in '/home/alleni/cst/lab12exercise/passwd' awk: cmd. line:1: $1 == """ {print $4} awk: cmd. line:1: ^ unterminated string ./50_group_lister.sh: Cannot find group ID for '"' in file '/home/alleni/cst/lab12exercise/passwd' Failing to bullet-proof program input, especially script input, especially script input that is accessible from the Web, may open up security holes on your machine. Always validate your input! How would you prevent the user from passing in any double-quote characters as part of the userid?