Insanify configuration files

This commit is contained in:
Michael Spang 2009-07-29 13:03:32 -04:00
parent 92652a3af0
commit ad30f9c47a
17 changed files with 211 additions and 101 deletions

View File

@ -23,11 +23,9 @@ cfg = {}
def configure():
"""Load Members Configuration"""
string_fields = [ 'username_regex', 'shells_file', 'server_url',
'users_base', 'groups_base', 'sasl_mech', 'sasl_realm',
'admin_bind_keytab', 'admin_bind_userid', 'realm',
'admin_principal', 'expired_account_email',
'mathsoc_regex', 'mathsoc_dont_count' ]
string_fields = [ 'username_regex', 'shells_file', 'ldap_server_url',
'ldap_users_base', 'ldap_groups_base', 'ldap_sasl_mech', 'ldap_sasl_realm',
'expire_hook', 'mathsoc_regex', 'mathsoc_dont_count' ]
numeric_fields = [ 'min_password_length' ]
# read configuration file
@ -93,8 +91,8 @@ def connect(auth_callback):
tries = 0
while ld is None:
try:
ld = ldapi.connect_sasl(cfg['server_url'], cfg['sasl_mech'],
cfg['sasl_realm'], password)
ld = ldapi.connect_sasl(cfg['ldap_server_url'], cfg['ldap_sasl_mech'],
cfg['ldap_sasl_realm'], password)
except ldap.LOCAL_ERROR, e:
tries += 1
if tries > 3:
@ -172,10 +170,10 @@ def get(userid):
}
"""
return ldapi.lookup(ld, 'uid', userid, cfg['users_base'])
return ldapi.lookup(ld, 'uid', userid, cfg['ldap_users_base'])
def uid2dn(uid):
return 'uid=%s,%s' % (ldapi.escape(uid), cfg['users_base'])
return 'uid=%s,%s' % (ldapi.escape(uid), cfg['ldap_users_base'])
def list_term(term):
@ -194,7 +192,7 @@ def list_term(term):
}
"""
members = ldapi.search(ld, cfg['users_base'],
members = ldapi.search(ld, cfg['ldap_users_base'],
'(&(objectClass=member)(term=%s))', [ term ])
return dict([(member[0], member[1]) for member in members])
@ -214,7 +212,7 @@ def list_name(name):
]
"""
members = ldapi.search(ld, cfg['users_base'],
members = ldapi.search(ld, cfg['ldap_users_base'],
'(&(objectClass=member)(cn~=%s))', [ name ])
return dict([(member[0], member[1]) for member in members])
@ -256,7 +254,7 @@ def list_all():
]
"""
members = ldapi.search(ld, cfg['users_base'], '(objectClass=member)')
members = ldapi.search(ld, cfg['ldap_users_base'], '(objectClass=member)')
return dict([(member[0], member[1]) for member in members])
@ -272,7 +270,7 @@ def list_positions():
]
"""
members = ld.search_s(cfg['users_base'], ldap.SCOPE_SUBTREE, '(position=*)')
members = ld.search_s(cfg['ldap_users_base'], ldap.SCOPE_SUBTREE, '(position=*)')
positions = {}
for (_, member) in members:
for position in member['position']:
@ -293,7 +291,7 @@ def set_position(position, members):
Example: set_position('president', ['dtbartle'])
"""
res = ld.search_s(cfg['users_base'], ldap.SCOPE_SUBTREE,
res = ld.search_s(cfg['ldap_users_base'], ldap.SCOPE_SUBTREE,
'(&(objectClass=member)(position=%s))' % ldapi.escape(position))
old = set([ member['uid'][0] for (_, member) in res ])
new = set(members)
@ -306,7 +304,7 @@ def set_position(position, members):
for action in ['del', 'add']:
for userid in mods[action]:
dn = 'uid=%s,%s' % (ldapi.escape(userid), cfg['users_base'])
dn = 'uid=%s,%s' % (ldapi.escape(userid), cfg['ldap_users_base'])
entry1 = {'position' : [position]}
entry2 = {} #{'position' : []}
entry = ()
@ -319,8 +317,8 @@ def set_position(position, members):
def change_group_member(action, group, userid):
user_dn = 'uid=%s,%s' % (ldapi.escape(userid), cfg['users_base'])
group_dn = 'cn=%s,%s' % (ldapi.escape(group), cfg['groups_base'])
user_dn = 'uid=%s,%s' % (ldapi.escape(userid), cfg['ldap_users_base'])
group_dn = 'cn=%s,%s' % (ldapi.escape(group), cfg['ldap_groups_base'])
entry1 = {'uniqueMember' : []}
entry2 = {'uniqueMember' : [user_dn]}
entry = []
@ -338,7 +336,7 @@ def change_group_member(action, group, userid):
### Shells ###
def get_shell(userid):
member = ldapi.lookup(ld, 'uid', userid, cfg['users_base'])
member = ldapi.lookup(ld, 'uid', userid, cfg['ldap_users_base'])
if not member:
raise NoSuchMember(userid)
if 'loginShell' not in member:
@ -357,7 +355,7 @@ def get_shells():
def set_shell(userid, shell):
if not shell in get_shells():
raise InvalidArgument("shell", shell, "is not in %s" % cfg['shells_file'])
ldapi.modify(ld, 'uid', userid, cfg['users_base'], [ (ldap.MOD_REPLACE, 'loginShell', [ shell ]) ])
ldapi.modify(ld, 'uid', userid, cfg['ldap_users_base'], [ (ldap.MOD_REPLACE, 'loginShell', [ shell ]) ])
@ -414,7 +412,7 @@ def register(userid, term_list):
Example: register(3349, ["w2007", "s2007"])
"""
user_dn = 'uid=%s,%s' % (ldapi.escape(userid), cfg['users_base'])
user_dn = 'uid=%s,%s' % (ldapi.escape(userid), cfg['ldap_users_base'])
if type(term_list) in (str, unicode):
term_list = [ term_list ]
@ -446,7 +444,7 @@ def register(userid, term_list):
def register_nonmember(userid, term_list):
"""Registers a non-member for one or more terms."""
user_dn = 'uid=%s,%s' % (ldapi.escape(userid), cfg['users_base'])
user_dn = 'uid=%s,%s' % (ldapi.escape(userid), cfg['ldap_users_base'])
if type(term_list) in (str, unicode):
term_list = [ term_list ]
@ -505,7 +503,7 @@ def group_members(group):
Returns a list of group members
"""
group = ldapi.lookup(ld, 'cn', group, cfg['groups_base'])
group = ldapi.lookup(ld, 'cn', group, cfg['ldap_groups_base'])
if group and 'uniqueMember' in group:
r = re.compile('^uid=([^,]*)')
@ -513,11 +511,11 @@ def group_members(group):
return []
def expired_accounts():
members = ldapi.search(ld, cfg['users_base'],
members = ldapi.search(ld, cfg['ldap_users_base'],
'(&(objectClass=member)(!(|(term=%s)(nonMemberTerm=%s))))' %
(terms.current(), terms.current()))
return dict([(member[0], member[1]) for member in members])
def send_account_expired_email(name, email):
args = [ cfg['expired_account_email'], name, email ]
os.spawnv(os.P_WAIT, cfg['expired_account_email'], args)
args = [ cfg['expire_hook'], name, email ]
os.spawnv(os.P_WAIT, cfg['expire_hook'], args)

View File

@ -1 +1 @@
etc/accounts.cf etc/kerberos.cf etc/ldap.cf etc/csc
etc/accounts.cf etc/library.cf etc/ops etc/spam etc/csc

View File

@ -1,17 +1,13 @@
# /etc/csc/accounts.cf: CSC Accounts Configuration
include /etc/csc/ldap.cf
include /etc/csc/kerberos.cf
### Member Account Options ###
member_min_id = 20001
member_max_id = 29999
member_shell = "/bin/bash"
member_home = "/users"
#member_home_acl = "u::rwx,g::rx,o::rx"
#member_home_dacl =
member_home_acl =
member_home_acl = "u::rwx,g::rx,o::rx"
member_home_skel = "/users/skel"
### Club Account Options ###
@ -20,27 +16,37 @@ club_max_id = 39999
club_shell = "/bin/bash"
club_home = "/users"
club_home_acl = "A+group:%s:rwpRAxaWdDcCs:fd:allow"
club_home_skel = "/users/skel"
### Administrative Account Options
### Administrative Account Options ###
admin_min_id = 10001
admin_max_id = 19999
admin_shell = "/bin/bash"
admin_home = "/users"
### Home Directory Options ###
### LDAP Options ###
skeleton_dir = "/users/skel"
homedir_mode = "0755"
refquota = "4G"
ldap_server_url = "ldaps://ldap-master.csclub.uwaterloo.ca"
ldap_users_base = "ou=People,dc=csclub,dc=uwaterloo,dc=ca"
ldap_groups_base = "ou=Group,dc=csclub,dc=uwaterloo,dc=ca"
ldap_sudo_base = "ou=SUDOers,dc=csclub,dc=uwaterloo,dc=ca"
ldap_sasl_mech = "GSSAPI"
ldap_sasl_realm = "CSCLUB.UWATERLOO.CA"
ldap_admin_principal = "ceod/admin@CSCLUB.UWATERLOO.CA"
### Validation Tuning ###
### Kerberos Options ###
krb5_realm = "CSCLUB.UWATERLOO.CA"
krb5_admin_principal = "ceod/admin@CSCLUB.UWATERLOO.CA"
### Spam ###
notify_hook = "/etc/csc/spam/new-member"
expire_hook = "/etc/csc/spam/expired-account"
### Miscellaneous ###
username_regex = "^[a-z][-a-z0-9]*$"
min_password_length = 4
shells_file = "/etc/shells"
privileged_group = "staff"
notify_hook = "/etc/csc/notify-hook"
expired_account_email = "/etc/csc/expired-account"
mathsoc_regex = ".*(mat/|vpa/se|computer science|math).*"
mathsoc_dont_count = "cpdohert dlgawley dtbartle mbiggs saforres tmyklebu"
mathsoc_dont_count = "cpdohert dlgawley dtbartle mbiggs saforres tmyklebu mgregson rridge dbelange"

View File

@ -1,5 +0,0 @@
# /etc/csc/kerberos.cf: CSC Kerberos Administration Configuration
realm = "CSCLUB.UWATERLOO.CA"
admin_principal = "ceo/admin@CSCLUB.UWATERLOO.CA"
admin_keytab = "/etc/csc/ceo.keytab"

View File

@ -1,14 +0,0 @@
# /etc/csc/ldap.cf: CSC LDAP Configuration
server_url = "ldaps:///"
users_base = "ou=People,dc=csclub,dc=uwaterloo,dc=ca"
groups_base = "ou=Group,dc=csclub,dc=uwaterloo,dc=ca"
sudo_base = "ou=SUDOers,dc=csclub,dc=uwaterloo,dc=ca"
admin_bind_dn =
admin_bind_keytab = "/etc/csc/ceo.keytab"
admin_bind_userid = "ceo"
sasl_mech = "GSSAPI"
sasl_realm = "CSCLUB.UWATERLOO.CA"

4
etc/library.cf Normal file
View File

@ -0,0 +1,4 @@
# /etc/csc/library.cf: Library Config
library_connect_string = "postgres://librarian:PWPWPWPWPWPWPWPWPWPW@127.0.0.1/library"
aws_account_key = "KEYKEYKEYKEYKEYKEYKY"

1
etc/ops/adduser Normal file
View File

@ -0,0 +1 @@
ginseng adduser 0x01

49
etc/spam/expired-account Executable file
View File

@ -0,0 +1,49 @@
#!/bin/sh
name=$1
email=$2
shift 2
tmp="$(tempfile)"
trap "rm $tmp" 0
exec >"$tmp"
echo "From: Computer Science Club <ceo+expired@csclub.uwaterloo.ca>"
echo "Reply-to: CSClub Exec <exec@csclub.uwaterloo.ca>"
echo "To: $name <$email>"
echo "Subject: [CSClub] Account Expiration"
echo ""
echo "Hello,
We noticed that your Computer Science Club membership has expired. We would
like to remind you of the many benefits of being a member of the club:
* 4 GiB of disk quota
* Web space
* Email address
* Shell account
* Access to our library
If you would like to renew your membership (the fee is \$2 per term), we have
various methods of doing so:
* Come by our office (MC 3036)
* Send us a PayPal donation and send us the transaction id; see
http://csclub.uwaterloo.ca/about/donations for details
* Mail us a cheque; here's our address:
Computer Science Club
Math & Computer 3036/3037
University of Waterloo
200 University Avenue West
Waterloo, ON N3L 3G1
Canada
If you have any questions, feel free to contact us by phone at
(519) 888-4567 x33870, or by email at exec@csclub.uwaterloo.ca.
Regards,
The Computer Science Club"
exec >&- 2>&-
/usr/sbin/sendmail -t -f "ceo@csclub.uwaterloo.ca" < "$tmp"

71
etc/spam/new-member Executable file
View File

@ -0,0 +1,71 @@
#!/bin/bash -p
# This is a privileged script.
IFS=$' \t\n'
PATH=/usr/bin:/bin
unset ENV BASH_ENV CDPATH
umask 077
prog=$1
auth=$2
shift 2
tmp="$(tempfile)"
trap "rm $tmp" 0
exec >"$tmp"
authrn="$(getent passwd "$auth" | awk -F: '{ print $5 }' | sed -e 's/,.*//')"
h_from="$prog <ceo+$prog@csclub.uwaterloo.ca>"
h_to="Membership and Accounts <ceo@csclub.uwaterloo.ca>"
h_cc="$authrn <$auth@csclub.uwaterloo.ca>"
if test "$prog" = addmember; then
user=$1 name=$2 dept=$3 status=$4; shift 4
subj="New Member: $user"
test -z "$dept" && dept="things unknown"
body="Name: $name
Account: $user
Program: $dept
Added by: $auth"
elif test "$prog" = addclub; then
user=$1 name=$2 status=$4; shift 4
subj="New Club Account: $user"
body="Club: $name
Account: $user
Added by: $auth"
else
exit 1
fi
output=$(cat)
if test "$status" = "failure"; then
subj="$subj (FAILURES)"
fi
echo "From: $h_from"
echo "To: $h_to"
echo "Cc: $h_cc"
echo "X-Auth-User: $auth"
echo "X-New-User: $user"
echo "X-New-Name: $name"
echo "Subject: $subj"
echo
echo "$body" | fmt -s
echo
if test "$status" = "success"; then
echo all failures went undetected
elif test -n "$output"; then
echo "$output"
fi
echo
echo Your Friend,
echo "$prog"
exec >&2
env - /usr/sbin/sendmail -t -f "ceo@csclub.uwaterloo.ca" < "$tmp"

View File

@ -1,24 +1,24 @@
CONFIG_STR(server_url)
CONFIG_STR(users_base)
CONFIG_STR(groups_base)
CONFIG_STR(sudo_base)
CONFIG_STR(skeleton_dir)
CONFIG_STR(member_shell)
CONFIG_INT(member_min_id)
CONFIG_INT(member_max_id)
CONFIG_STR(member_home)
CONFIG_STR(member_home_skel)
CONFIG_STR(club_shell)
CONFIG_INT(club_min_id)
CONFIG_INT(club_max_id)
CONFIG_STR(club_home)
CONFIG_STR(club_home_skel)
CONFIG_STR(notify_hook)
CONFIG_STR(realm)
CONFIG_STR(krb5_realm)
CONFIG_STR(krb5_admin_principal)
CONFIG_STR(admin_principal)
CONFIG_STR(admin_bind_userid)
CONFIG_STR(ldap_server_url)
CONFIG_STR(ldap_users_base)
CONFIG_STR(ldap_groups_base)
CONFIG_STR(ldap_sudo_base)
CONFIG_STR(ldap_sasl_mech)
CONFIG_STR(ldap_sasl_realm)
CONFIG_STR(ldap_admin_principal)

View File

@ -11,9 +11,9 @@
#include "util.h"
#include "config.h"
int ceo_create_home(char *homedir, uid_t uid, gid_t gid) {
int ceo_create_home(char *homedir, char *skel, uid_t uid, gid_t gid) {
int mask;
DIR *skel;
DIR *skeldir;
struct dirent *skelent;
mask = umask(0);
@ -23,20 +23,20 @@ int ceo_create_home(char *homedir, uid_t uid, gid_t gid) {
return -1;
}
skel = opendir(skeleton_dir);
if (!skel) {
errorpe("failed to open %s", skeleton_dir);
skeldir = opendir(skel);
if (!skeldir) {
errorpe("failed to open %s", skel);
return -1;
}
while ((skelent = readdir(skel))) {
while ((skelent = readdir(skeldir))) {
struct stat sb;
char src[PATH_MAX], dest[PATH_MAX];
if (!strcmp(skelent->d_name, ".") || !strcmp(skelent->d_name, ".."))
continue;
snprintf(src, sizeof(src), "%s/%s", skeleton_dir, skelent->d_name);
snprintf(src, sizeof(src), "%s/%s", skel, skelent->d_name);
snprintf(dest, sizeof(dest), "%s/%s", homedir, skelent->d_name);
lstat(src, &sb);
@ -108,7 +108,7 @@ int ceo_create_home(char *homedir, uid_t uid, gid_t gid) {
}
}
closedir(skel);
closedir(skeldir);
if (chown(homedir, uid, gid)) {
errorpe("failed to chown %s", homedir);

View File

@ -1,3 +1,3 @@
#include <sys/acl.h>
int ceo_create_home(char *homedir, uid_t uid, gid_t gid);
int ceo_create_home(char *homedir, char *skel, uid_t uid, gid_t gid);

View File

@ -14,9 +14,9 @@ void ceo_kadm_init() {
kadm5_config_params params;
memset((void *) &params, 0, sizeof(params));
debug("kadmin: initializing using keytab for %s", admin_principal);
debug("kadmin: initializing using keytab for %s", krb5_admin_principal);
retval = kadm5_init_with_skey(admin_principal, NULL,
retval = kadm5_init_with_skey(krb5_admin_principal, NULL,
KADM5_ADMIN_SERVICE, &params, KADM5_STRUCT_VERSION,
KADM5_API_VERSION_2, NULL, &handle);
if (retval || !handle) {

View File

@ -41,7 +41,7 @@ void ceo_krb5_init() {
if (retval)
com_err(prog, retval, "while initializing krb5");
retval = krb5_set_default_realm(context, realm);
retval = krb5_set_default_realm(context, krb5_realm);
if (retval)
com_err(prog, retval, "while setting default realm");
}
@ -59,7 +59,7 @@ void ceo_krb5_auth(char *principal) {
debug("krb5: getting TGT using keytab for %s", principal);
if ((retval = krb5_parse_name(context, principal, &princ)))
com_err(prog, retval, "while resolving user %s", admin_bind_userid);
com_err(prog, retval, "while resolving user %s", principal);
if ((retval = krb5_cc_default(context, &cache)))
com_err(prog, retval, "while resolving credentials cache");

View File

@ -277,7 +277,7 @@ int ceo_new_uid(int min, int max) {
continue;
snprintf(filter, sizeof(filter), "(|(uidNumber=%d)(gidNumber=%d))", i, i);
if (ldap_search_s(ld, users_base, LDAP_SCOPE_SUBTREE, filter, attrs, 1, &res) != LDAP_SUCCESS) {
if (ldap_search_s(ld, ldap_users_base, LDAP_SCOPE_SUBTREE, filter, attrs, 1, &res) != LDAP_SUCCESS) {
ldap_err("firstuid");
return -1;
}
@ -306,7 +306,7 @@ int ceo_user_exists(char *uid) {
snprintf(filter, sizeof(filter), "uid=%s", uid);
if (ldap_search_s(ld, users_base, LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg) != LDAP_SUCCESS) {
if (ldap_search_s(ld, ldap_users_base, LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg) != LDAP_SUCCESS) {
ldap_err("user_exists");
return -1;
}
@ -328,7 +328,7 @@ int ceo_group_exists(char *cn) {
snprintf(filter, sizeof(filter), "cn=%s", cn);
if (ldap_search_s(ld, groups_base, LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg) != LDAP_SUCCESS) {
if (ldap_search_s(ld, ldap_groups_base, LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg) != LDAP_SUCCESS) {
ldap_err("group_exists");
return -1;
}
@ -362,10 +362,10 @@ void ceo_ldap_init() {
int proto = LDAP_DEFAULT_PROTOCOL;
const char *sasl_mech = "GSSAPI";
if (!admin_bind_userid)
if (!ldap_admin_principal)
fatal("not configured");
if (ldap_initialize(&ld, server_url) != LDAP_SUCCESS)
if (ldap_initialize(&ld, ldap_server_url) != LDAP_SUCCESS)
ldap_fatal("ldap_initialize");
if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &proto) != LDAP_OPT_SUCCESS)

View File

@ -154,19 +154,19 @@ static int32_t addmember(Ceo__AddUser *in, Ceo__AddUserResponse *out) {
return response_message(out, EKERB, "unable to create kerberos principal %s", in->username);
response_message(out, 0, "successfully created principal");
if ((user_stat = ceo_add_user(in->username, users_base, "member", in->realname, homedir,
if ((user_stat = ceo_add_user(in->username, ldap_users_base, "member", in->realname, homedir,
member_shell, id, "program", in->program, NULL)))
return response_message(out, ELDAP, "unable to create ldap account %s", in->username);
response_message(out, 0, "successfully created ldap account");
/* errors that occur after this point are not fatal */
if ((group_stat = ceo_add_group(in->username, groups_base, id)))
if ((group_stat = ceo_add_group(in->username, ldap_groups_base, id)))
response_message(out, ELDAP, "unable to create ldap group %s", in->username);
else
response_message(out, 0, "successfully created ldap group");
if ((home_stat = ceo_create_home(homedir, id, id)))
if ((home_stat = ceo_create_home(homedir, member_home_skel, id, id)))
response_message(out, EHOME, "unable to create home directory for %s", in->username);
else
response_message(out, 0, "successfully created home directory");
@ -190,24 +190,24 @@ static int32_t addclub(Ceo__AddUser *in, Ceo__AddUserResponse *out) {
if ((krb_stat = ceo_del_princ(in->username)))
return response_message(out, EKERB, "unable to clear principal %s", in->username);
if ((user_stat = ceo_add_user(in->username, users_base, "club", in->realname, homedir,
if ((user_stat = ceo_add_user(in->username, ldap_users_base, "club", in->realname, homedir,
club_shell, id, NULL)))
return response_message(out, ELDAP, "unable to create ldap account %s", in->username);
response_message(out, 0, "successfully created ldap account");
/* errors that occur after this point are not fatal */
if ((group_stat = ceo_add_group(in->username, groups_base, id)))
if ((group_stat = ceo_add_group(in->username, ldap_groups_base, id)))
response_message(out, ELDAP, "unable to create ldap group %s", in->username);
else
response_message(out, 0, "successfully created ldap group");
if ((sudo_stat = ceo_add_group_sudo(in->username, sudo_base)))
if ((sudo_stat = ceo_add_group_sudo(in->username, ldap_sudo_base)))
response_message(out, ELDAP, "unable to create ldap sudoers %s", in->username);
else
response_message(out, 0, "successfully created ldap sudoers");
if ((home_stat = ceo_create_home(homedir, id, id)))
if ((home_stat = ceo_create_home(homedir, club_home_skel, id, id)))
response_message(out, EHOME, "unable to create home directory for %s", in->username);
else
response_message(out, 0, "successfully created home directory");
@ -282,7 +282,7 @@ int main(int argc, char *argv[]) {
fatalpe("setenv");
ceo_krb5_init();
ceo_krb5_auth(admin_bind_userid);
ceo_krb5_auth(ldap_admin_principal);
ceo_ldap_init();
ceo_kadm_init();

View File

@ -68,7 +68,7 @@ void setup_ops(void) {
op_dir = getenv("CEO_LIB_DIR") ?: default_op_dir;
if (snprintf(op_config_dir, sizeof(op_config_dir), "%s/%s", config_dir, "ops.d") >= sizeof(op_config_dir))
if (snprintf(op_config_dir, sizeof(op_config_dir), "%s/%s", config_dir, "ops") >= sizeof(op_config_dir))
fatal("ops dir path too long");
dp = opendir(op_config_dir);