POSIX ACL support in addhomedir and addclub
authorMichael Spang <mspang@csclub.uwaterloo.ca>
Thu, 20 Dec 2007 07:25:29 +0000 (02:25 -0500)
committerMichael Spang <mspang@csclub.uwaterloo.ca>
Thu, 20 Dec 2007 07:27:51 +0000 (02:27 -0500)
src/Makefile
src/addclub.c
src/addhomedir.c
src/addhomedir.h
src/addmember.c
src/config.c
src/config.h

index 840763d..3fdcd19 100644 (file)
@@ -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 $@
index 257cebc..becc7dc 100644 (file)
@@ -1,6 +1,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/acl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <getopt.h>
@@ -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);
 
index c2ad7fa..6cd27db 100644 (file)
@@ -2,6 +2,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/acl.h>
 #include <dirent.h>
 #include <pwd.h>
 #include <fcntl.h>
 #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);
 
index 50f7062..560dbc8 100644 (file)
@@ -1,4 +1,4 @@
 #include <sys/types.h>
 
-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);
index 9f35078..16a2076 100644 (file)
@@ -1,6 +1,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/acl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <getopt.h>
@@ -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);
 
index c4ba3a8..b805d13 100644 (file)
@@ -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, &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 *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) {
index bd7c20d..8bf4c72 100644 (file)
@@ -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;