Resurrect linux homedir support
This commit is contained in:
parent
0d52c0475b
commit
37eb3e6465
|
@ -2,7 +2,7 @@ Source: ceo
|
||||||
Section: admin
|
Section: admin
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Systems Committee <syscom@csclub.uwaterloo.ca>
|
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
|
Standards-Version: 3.8.2
|
||||||
|
|
||||||
Package: ceo
|
Package: ceo
|
||||||
|
|
|
@ -16,6 +16,9 @@ LDAP_PROGS := addmember addclub op-adduser
|
||||||
KRB5_OBJECTS := krb5.o kadm.o
|
KRB5_OBJECTS := krb5.o kadm.o
|
||||||
KRB5_LDFLAGS := $(shell krb5-config --libs krb5 kadm-client)
|
KRB5_LDFLAGS := $(shell krb5-config --libs krb5 kadm-client)
|
||||||
KRB5_PROGS := addmember addclub op-adduser
|
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_OBJECTS := net.o gss.o ops.o
|
||||||
NET_LDFLAGS := -lsctp $(shell krb5-config --libs gssapi)
|
NET_LDFLAGS := -lsctp $(shell krb5-config --libs gssapi)
|
||||||
NET_PROGS := ceod ceoc
|
NET_PROGS := ceod ceoc
|
||||||
|
@ -57,6 +60,8 @@ $(LDAP_PROGS): LDFLAGS += $(LDAP_LDFLAGS)
|
||||||
$(LDAP_PROGS): $(LDAP_OBJECTS)
|
$(LDAP_PROGS): $(LDAP_OBJECTS)
|
||||||
$(KRB5_PROGS): LDFLAGS += $(KRB5_LDFLAGS)
|
$(KRB5_PROGS): LDFLAGS += $(KRB5_LDFLAGS)
|
||||||
$(KRB5_PROGS): $(KRB5_OBJECTS)
|
$(KRB5_PROGS): $(KRB5_OBJECTS)
|
||||||
|
$(HOME_PROGS): LDFLAGS += $(HOME_LDFLAGS)
|
||||||
|
$(HOME_PROGS): $(HOME_OBJECTS)
|
||||||
$(PROTO_PROGS): LDFLAGS += $(PROTO_LDFLAGS)
|
$(PROTO_PROGS): LDFLAGS += $(PROTO_LDFLAGS)
|
||||||
$(PROTO_PROGS): $(PROTO_OBJECTS)
|
$(PROTO_PROGS): $(PROTO_OBJECTS)
|
||||||
$(CONFIG_PROGS): LDFLAGS += $(CONFIG_LDFLAGS)
|
$(CONFIG_PROGS): LDFLAGS += $(CONFIG_LDFLAGS)
|
||||||
|
|
|
@ -5,20 +5,16 @@ CONFIG_STR(groups_base)
|
||||||
CONFIG_STR(sudo_base)
|
CONFIG_STR(sudo_base)
|
||||||
|
|
||||||
CONFIG_STR(skeleton_dir)
|
CONFIG_STR(skeleton_dir)
|
||||||
CONFIG_STR(homedir_mode)
|
|
||||||
CONFIG_STR(refquota)
|
|
||||||
|
|
||||||
CONFIG_STR(member_shell)
|
CONFIG_STR(member_shell)
|
||||||
CONFIG_INT(member_min_id)
|
CONFIG_INT(member_min_id)
|
||||||
CONFIG_INT(member_max_id)
|
CONFIG_INT(member_max_id)
|
||||||
CONFIG_STR(member_home)
|
CONFIG_STR(member_home)
|
||||||
CONFIG_STR(member_home_acl)
|
|
||||||
|
|
||||||
CONFIG_STR(club_shell)
|
CONFIG_STR(club_shell)
|
||||||
CONFIG_INT(club_min_id)
|
CONFIG_INT(club_min_id)
|
||||||
CONFIG_INT(club_max_id)
|
CONFIG_INT(club_max_id)
|
||||||
CONFIG_STR(club_home)
|
CONFIG_STR(club_home)
|
||||||
CONFIG_STR(club_home_acl)
|
|
||||||
|
|
||||||
CONFIG_STR(notify_hook)
|
CONFIG_STR(notify_hook)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include <sys/acl.h>
|
||||||
|
|
||||||
|
int ceo_create_home(char *homedir, uid_t uid, gid_t gid);
|
|
@ -19,6 +19,7 @@
|
||||||
#include "gss.h"
|
#include "gss.h"
|
||||||
#include "krb5.h"
|
#include "krb5.h"
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
#include "homedir.h"
|
||||||
#include "kadm.h"
|
#include "kadm.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
@ -136,7 +137,7 @@ static void adduser_spam(Ceo__AddUser *in, Ceo__AddUserResponse *out, char *clie
|
||||||
|
|
||||||
static int32_t addmember(Ceo__AddUser *in, Ceo__AddUserResponse *out) {
|
static int32_t addmember(Ceo__AddUser *in, Ceo__AddUserResponse *out) {
|
||||||
char homedir[1024];
|
char homedir[1024];
|
||||||
int user_stat, group_stat, krb_stat;
|
int user_stat, group_stat, krb_stat, home_stat;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
if (snprintf(homedir, sizeof(homedir), "%s/%s",
|
if (snprintf(homedir, sizeof(homedir), "%s/%s",
|
||||||
|
@ -165,12 +166,15 @@ static int32_t addmember(Ceo__AddUser *in, Ceo__AddUserResponse *out) {
|
||||||
else
|
else
|
||||||
response_message(out, 0, "successfully created ldap group");
|
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) {
|
static int32_t addclub(Ceo__AddUser *in, Ceo__AddUserResponse *out) {
|
||||||
char homedir[1024];
|
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;
|
int id;
|
||||||
|
|
||||||
if (snprintf(homedir, sizeof(homedir), "%s/%s",
|
if (snprintf(homedir, sizeof(homedir), "%s/%s",
|
||||||
|
@ -200,7 +204,10 @@ static int32_t addclub(Ceo__AddUser *in, Ceo__AddUserResponse *out) {
|
||||||
else
|
else
|
||||||
response_message(out, 0, "successfully created ldap sudoers");
|
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) {
|
static int32_t adduser(Ceo__AddUser *in, Ceo__AddUserResponse *out, char *client) {
|
||||||
|
|
Loading…
Reference in New Issue