Section: admin
Priority: optional
Maintainer: Systems Committee <syscom@csclub.uwaterloo.ca>
-Build-Depends: debhelper (>= 5.0.0), python-dev (>= 2.4), python-support (>= 0.3), libkrb5-dev, libldap2-dev, libsasl2-dev, libsctp-dev, libprotobuf-c0-dev
+Build-Depends: debhelper (>= 5.0.0), python-dev (>= 2.4), python-support (>= 0.3), libkrb5-dev, libldap2-dev, libsasl2-dev, libsctp-dev, libprotobuf-c0-dev, libacl1-dev
Standards-Version: 3.8.2
Package: ceo
KRB5_OBJECTS := krb5.o kadm.o
KRB5_LDFLAGS := $(shell krb5-config --libs krb5 kadm-client)
KRB5_PROGS := addmember addclub op-adduser
+HOME_OBJECTS := homedir.o
+HOME_LDFLAGS := -lacl
+HOME_PROGS := op-adduser
NET_OBJECTS := net.o gss.o ops.o
NET_LDFLAGS := -lsctp $(shell krb5-config --libs gssapi)
NET_PROGS := ceod ceoc
$(LDAP_PROGS): $(LDAP_OBJECTS)
$(KRB5_PROGS): LDFLAGS += $(KRB5_LDFLAGS)
$(KRB5_PROGS): $(KRB5_OBJECTS)
+$(HOME_PROGS): LDFLAGS += $(HOME_LDFLAGS)
+$(HOME_PROGS): $(HOME_OBJECTS)
$(PROTO_PROGS): LDFLAGS += $(PROTO_LDFLAGS)
$(PROTO_PROGS): $(PROTO_OBJECTS)
$(CONFIG_PROGS): LDFLAGS += $(CONFIG_LDFLAGS)
CONFIG_STR(sudo_base)
CONFIG_STR(skeleton_dir)
-CONFIG_STR(homedir_mode)
-CONFIG_STR(refquota)
CONFIG_STR(member_shell)
CONFIG_INT(member_min_id)
CONFIG_INT(member_max_id)
CONFIG_STR(member_home)
-CONFIG_STR(member_home_acl)
CONFIG_STR(club_shell)
CONFIG_INT(club_min_id)
CONFIG_INT(club_max_id)
CONFIG_STR(club_home)
-CONFIG_STR(club_home_acl)
CONFIG_STR(notify_hook)
--- /dev/null
+#include <stdio.h>
+#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 "homedir.h"
+#include "util.h"
+#include "config.h"
+
+int ceo_create_home(char *homedir, uid_t uid, gid_t gid) {
+ int mask;
+ DIR *skel;
+ struct dirent *skelent;
+
+ mask = umask(0);
+
+ if (mkdir(homedir, 0755)) {
+ errorpe("failed to create %s", homedir);
+ return -1;
+ }
+
+ skel = opendir(skeleton_dir);
+ if (!skel) {
+ errorpe("failed to open %s", skeleton_dir);
+ return -1;
+ }
+
+ while ((skelent = readdir(skel))) {
+ 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(dest, sizeof(dest), "%s/%s", homedir, skelent->d_name);
+ lstat(src, &sb);
+
+ if (sb.st_uid || sb.st_gid) {
+ warn("not creating %s due to ownership", dest);
+ continue;
+ }
+
+ if (S_ISREG(sb.st_mode)) {
+ int bytes;
+ char buf[4096];
+
+ int srcfd = open(src, O_RDONLY);
+ if (srcfd == -1) {
+ warnpe("open: %s", src);
+ continue;
+ }
+
+ int destfd = open(dest, O_WRONLY|O_CREAT|O_EXCL, sb.st_mode & 0777);
+ if (destfd == -1) {
+ warnpe("open: %s", dest);
+ close(srcfd);
+ continue;
+ }
+
+ for (;;) {
+ bytes = read(srcfd, buf, sizeof(buf));
+ if (!bytes)
+ break;
+ if (bytes < 0) {
+ warnpe("read");
+ break;
+ }
+ if (write(destfd, buf, bytes) < 0) {
+ warnpe("write");
+ break;
+ }
+ }
+
+ if (fchown(destfd, uid, gid))
+ errorpe("chown: %s", dest);
+
+ close(srcfd);
+ close(destfd);
+ } else if (S_ISDIR(sb.st_mode)) {
+ if (mkdir(dest, sb.st_mode & 0777)) {
+ warnpe("mkdir: %s", dest);
+ continue;
+ }
+ if (chown(dest, uid, gid))
+ errorpe("chown: %s", dest);
+ } else if (S_ISLNK(sb.st_mode)) {
+ char lnkdest[PATH_MAX];
+ int bytes;
+ bytes = readlink(src, lnkdest, sizeof(lnkdest));
+ lnkdest[bytes] = '\0';
+ if (bytes == -1) {
+ warnpe("readlink: %s", src);
+ continue;
+ }
+ if (symlink(lnkdest, dest)) {
+ warnpe("symlink: %s", dest);
+ continue;
+ }
+ if (lchown(dest, uid, gid))
+ errorpe("lchown: %s", dest);
+ } else {
+ warn("not creating %s", dest);
+ }
+ }
+
+ closedir(skel);
+
+ if (chown(homedir, uid, gid)) {
+ errorpe("failed to chown %s", homedir);
+ return -1;
+ }
+
+ umask(mask);
+
+ return 0;
+}
--- /dev/null
+#include <sys/acl.h>
+
+int ceo_create_home(char *homedir, uid_t uid, gid_t gid);
#include "gss.h"
#include "krb5.h"
#include "ldap.h"
+#include "homedir.h"
#include "kadm.h"
#include "daemon.h"
#include "strbuf.h"
static int32_t addmember(Ceo__AddUser *in, Ceo__AddUserResponse *out) {
char homedir[1024];
- int user_stat, group_stat, krb_stat;
+ int user_stat, group_stat, krb_stat, home_stat;
int id;
if (snprintf(homedir, sizeof(homedir), "%s/%s",
else
response_message(out, 0, "successfully created ldap group");
- return krb_stat || user_stat || group_stat;
+ if ((home_stat = ceo_create_home(homedir, id, id)))
+ notice("successfully created home directory for %s", in->username);
+
+ return krb_stat || user_stat || group_stat || home_stat;
}
static int32_t addclub(Ceo__AddUser *in, Ceo__AddUserResponse *out) {
char homedir[1024];
- int krb_stat, user_stat, group_stat, sudo_stat;
+ int krb_stat, user_stat, group_stat, sudo_stat, home_stat;
int id;
if (snprintf(homedir, sizeof(homedir), "%s/%s",
else
response_message(out, 0, "successfully created ldap sudoers");
- return user_stat || group_stat || sudo_stat;
+ if ((home_stat = ceo_create_home(homedir, id, id)))
+ notice("successfully created home directory for %s", in->username);
+
+ return user_stat || group_stat || sudo_stat || home_stat;
}
static int32_t adduser(Ceo__AddUser *in, Ceo__AddUserResponse *out, char *client) {