From e28b159cdc8a053803e95398c91ac0c761998d47 Mon Sep 17 00:00:00 2001 From: Michael Spang Date: Thu, 20 Dec 2007 02:25:29 -0500 Subject: [PATCH] POSIX ACL support in addhomedir and addclub --- src/Makefile | 13 ++++++------- src/addclub.c | 18 +++++++++++++++--- src/addhomedir.c | 19 ++++++++++++++++--- src/addhomedir.h | 2 +- src/addmember.c | 18 +++++++++++++++--- src/config.c | 20 ++++++++++++-------- src/config.h | 8 ++++++-- 7 files changed, 71 insertions(+), 27 deletions(-) diff --git a/src/Makefile b/src/Makefile index 840763d..3fdcd19 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,9 +1,8 @@ CFLAGS ?= -ggdb -Wall -O2 CFLAGS += -I../include -LDAP := -lldap -KADM := $(shell krb5-config --libs krb5 kadm-client) -LIBCEO := util.o common.o config.o parser.o ldap.o krb5.o kadm.o addhomedir.o +LIBCEO_OBJECTS := util.o common.o config.o parser.o ldap.o krb5.o kadm.o addhomedir.o +LIBCEO_LDFLAGS := -lacl -lldap $(shell krb5-config --libs krb5 kadm-client) DESTDIR := PREFIX := /usr/local @@ -13,11 +12,11 @@ all: addmember addclub clean: rm -f addmember addclub config-test *.o -addmember: $(LIBCEO) addmember.o - $(CC) $(LDFLAGS) $(LDAP) $(KADM) $^ -o $@ +addmember: $(LIBCEO_OBJECTS) addmember.o + $(CC) $(LDFLAGS) $(LIBCEO_LDFLAGS) $^ -o $@ -addclub: $(LIBCEO) addclub.o - $(CC) $(LDFLAGS) $(LDAP) $(KADM) $^ -o $@ +addclub: $(LIBCEO_OBJECTS) addclub.o + $(CC) $(LDFLAGS) $(LIBCEO_LDFLAGS) $^ -o $@ config-test: config-test.o parser.o util.o $(CC) $(LDFLAGS) $^ -o $@ diff --git a/src/addclub.c b/src/addclub.c index 257cebc..becc7dc 100644 --- a/src/addclub.c +++ b/src/addclub.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,7 @@ int addclub() { int krb_ok, user_ok, group_ok, sudo_ok, home_ok, quota_ok; int id; char homedir[1024]; + acl_t acl = NULL, dacl = NULL; logmsg("adding uid=%s cn=%s by %s", userid, name, user); @@ -53,6 +55,18 @@ int addclub() { if (!force && getpwnam(userid) != NULL) deny("user %s already exists", userid); + snprintf(homedir, sizeof(homedir), "%s/%s", club_home, userid); + + acl = acl_from_text(club_home_acl); + if (acl == NULL) + fatalpe("Unable to parse club_home_acl"); + + if (*club_home_acl) { + dacl = acl_from_text(club_home_dacl); + if (dacl == NULL) + fatalpe("Unable to parse club_home_dacl"); + } + ceo_krb5_init(); ceo_ldap_init(); ceo_kadm_init(); @@ -63,8 +77,6 @@ int addclub() { if ((id = ceo_new_uid(member_min_id, member_max_id)) <= 0) fatal("no available uids in range [%d, %d]", member_min_id, member_max_id); - snprintf(homedir, sizeof(homedir), "%s/%s", club_home, userid); - krb_ok = ceo_del_princ(userid); if (!krb_ok) logmsg("successfully cleared principal for %s", userid); @@ -82,7 +94,7 @@ int addclub() { if (!sudo_ok) logmsg("successfully added group sudo entry for %s", userid); - home_ok = user_ok || ceo_create_home(homedir, id, id); + home_ok = user_ok || ceo_create_home(homedir, id, id, acl, dacl); if (!home_ok) logmsg("successfully created home directory for %s", userid); diff --git a/src/addhomedir.c b/src/addhomedir.c index c2ad7fa..6cd27db 100644 --- a/src/addhomedir.c +++ b/src/addhomedir.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -10,14 +11,14 @@ #include "util.h" #include "config.h" -int ceo_create_home(char *homedir, uid_t uid, gid_t gid) { +int ceo_create_home(char *homedir, uid_t uid, gid_t gid, acl_t acl, acl_t dacl) { int mask; DIR *skel; struct dirent *skelent; mask = umask(0); - if (mkdir(homedir, homedir_mode)) { + if (mkdir(homedir, 0755)) { errorpe("failed to create %s", homedir); return -1; } @@ -109,8 +110,20 @@ int ceo_create_home(char *homedir, uid_t uid, gid_t gid) { closedir(skel); - if (chown(homedir, uid, gid)) + if (chown(homedir, uid, gid)) { errorpe("failed to chown %s", homedir); + return -1; + } + + if (acl && acl_set_file(homedir, ACL_TYPE_ACCESS, acl)) { + errorpe("failed to set acl for %s", homedir); + return -1; + } + + if (dacl && acl_set_file(homedir, ACL_TYPE_DEFAULT, dacl)) { + errorpe("failed to set default acl for %s", homedir); + return -1; + } umask(mask); diff --git a/src/addhomedir.h b/src/addhomedir.h index 50f7062..560dbc8 100644 --- a/src/addhomedir.h +++ b/src/addhomedir.h @@ -1,4 +1,4 @@ #include -int ceo_create_home(char *, uid_t, gid_t); +int ceo_create_home(char *, uid_t, gid_t, acl_t, acl_t); int ceo_set_quota(char *, int); diff --git a/src/addmember.c b/src/addmember.c index 9f35078..16a2076 100644 --- a/src/addmember.c +++ b/src/addmember.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ int addmember() { int krb_ok, user_ok, group_ok, home_ok, quota_ok; int id; char homedir[1024]; + acl_t acl = NULL, dacl = NULL; logmsg("adding uid=%s cn=%s program=%s by %s", userid, name, program, user); @@ -58,6 +60,18 @@ int addmember() { if (!force && getpwnam(userid) != NULL) deny("user %s already exists", userid); + snprintf(homedir, sizeof(homedir), "%s/%s", member_home, userid); + + acl = acl_from_text(member_home_acl); + if (acl == NULL) + fatalpe("Unable to parse member_home_acl"); + + if (*member_home_acl) { + dacl = acl_from_text(member_home_dacl); + if (dacl == NULL) + fatalpe("Unable to parse member_home_dacl"); + } + if (ceo_read_password(password, sizeof(password), use_stdin)) return 1; @@ -71,8 +85,6 @@ int addmember() { if ((id = ceo_new_uid(member_min_id, member_max_id)) <= 0) fatal("no available uids in range [%d, %d]", member_min_id, member_max_id); - snprintf(homedir, sizeof(homedir), "%s/%s", member_home, userid); - krb_ok = ceo_del_princ(userid); krb_ok = krb_ok || ceo_add_princ(userid, password); if (!krb_ok) @@ -87,7 +99,7 @@ int addmember() { if (!group_ok) logmsg("successfully created group for %s", userid); - home_ok = user_ok || ceo_create_home(homedir, id, id); + home_ok = user_ok || ceo_create_home(homedir, id, id, acl, dacl); if (!home_ok) logmsg("successfully created home directory for %s", userid); diff --git a/src/config.c b/src/config.c index c4ba3a8..b805d13 100644 --- a/src/config.c +++ b/src/config.c @@ -17,20 +17,22 @@ char *sudo_base = DEF_STR; char *skeleton_dir = DEF_STR; char *quota_prototype = DEF_STR; -char *member_home = DEF_STR; char *member_shell = DEF_STR; long member_min_id = DEF_LONG; long member_max_id = DEF_LONG; +char *member_home = DEF_STR; +char *member_home_acl = DEF_STR; +char *member_home_dacl = DEF_STR; -char *club_home = DEF_STR; char *club_shell = DEF_STR; long club_min_id = DEF_LONG; long club_max_id = DEF_LONG; +char *club_home = DEF_STR; +char *club_home_acl = DEF_STR; +char *club_home_dacl = DEF_STR; char *notify_hook = DEF_STR; -long homedir_mode = DEF_LONG; - char *realm = DEF_STR; char *admin_principal = DEF_STR; @@ -48,16 +50,18 @@ static char *strvarnames[] = { "server_url", "users_base", "admin_principal", "admin_keytab", "skeleton_dir", "quota_prototype", "member_home", "member_shell", "club_home", "club_shell", "realm", "admin_bind_userid", "admin_bind_keytab", "groups_base", "privileged_group", "notify_hook", - "sasl_realm", "sasl_mech", "sudo_base" }; + "sasl_realm", "sasl_mech", "sudo_base", "member_home_acl", + "member_home_dacl", "club_home_acl", "club_home_dacl" }; static char **strvars[] = { &server_url, &users_base, &admin_principal, &admin_keytab, &skeleton_dir, "a_prototype, &member_home, &member_shell, &club_home, &club_shell, &realm, &admin_bind_userid, &admin_bind_keytab, &groups_base, &privileged_group, ¬ify_hook, - &sasl_realm, &sasl_mech, &sudo_base }; + &sasl_realm, &sasl_mech, &sudo_base, &member_home_acl, &member_home_dacl, + &club_home_acl, &club_home_dacl }; static char *longvarnames[] = { "member_min_id", "member_max_id", - "homedir_mode", "club_min_id", "club_max_id" }; -static long *longvars[] = { &member_min_id, &member_max_id, &homedir_mode, + "club_min_id", "club_max_id" }; +static long *longvars[] = { &member_min_id, &member_max_id, &club_min_id, &club_max_id }; void config_var(char *var, char *val) { diff --git a/src/config.h b/src/config.h index bd7c20d..8bf4c72 100644 --- a/src/config.h +++ b/src/config.h @@ -8,15 +8,19 @@ extern char *sudo_base; extern char *skeleton_dir; extern char *quota_prototype; -extern char *member_home; extern char *member_shell; extern long member_min_id; extern long member_max_id; +extern char *member_home; +extern char *member_home_acl; +extern char *member_home_dacl; -extern char *club_home; extern char *club_shell; extern long club_min_id; extern long club_max_id; +extern char *club_home; +extern char *club_home_acl; +extern char *club_home_dacl; extern char *notify_hook;