You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
56 lines
1.6 KiB
56 lines
1.6 KiB
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <assert.h>
|
|
#include "util.h"
|
|
|
|
int main(int argc, char *argv[]) {
|
|
if(argc < 7) {
|
|
fprintf(stderr, "Usage: zfsaddhomedir homedir refquota skeldir uid gid mode acl\n");
|
|
return 1;
|
|
}
|
|
|
|
{
|
|
char *homedir = argv[1];
|
|
char *skeldir = argv[3];
|
|
char refquota[32];
|
|
char *mode = argv[6];
|
|
char *acl = (argc >= 8) ? argv[7] : NULL;
|
|
uid_t uid, gid;
|
|
char *zfs_bin = "/usr/sbin/zfs";
|
|
char *chmod_bin = "/usr/bin/chmod";
|
|
char *rsync_bin = "/usr/bin/rsync";
|
|
char *dataset = homedir + 1;
|
|
char *create_argv[] = { "zfs", "create", dataset, NULL };
|
|
char *quota_argv[] = { "zfs", "set", refquota, dataset, NULL };
|
|
char *mode_argv[] = { "chmod", mode, homedir, NULL };
|
|
char *acl_argv[] = { "chmod", acl, homedir, NULL };
|
|
char *rsync_argv[] = { "rsync", "-avH", skeldir, homedir, NULL };
|
|
|
|
assert(homedir[0]);
|
|
uid = atol(argv[4]);
|
|
gid = atol(argv[5]);
|
|
snprintf(refquota, sizeof(refquota), "refquota=%s", argv[2]);
|
|
|
|
if(spawnv(zfs_bin, create_argv))
|
|
return 1;
|
|
if(spawnv(zfs_bin, quota_argv))
|
|
return 1;
|
|
if(spawnv(chmod_bin, mode_argv))
|
|
return 1;
|
|
if(acl && spawnv(chmod_bin, acl_argv))
|
|
return 1;
|
|
|
|
if (chown(homedir, uid, gid)) {
|
|
errorpe("failed to chown %s", homedir);
|
|
return -1;
|
|
}
|
|
|
|
if(seteuid(uid) != 0 || setegid(gid) != 0)
|
|
return 1;
|
|
if(spawnv(rsync_bin, rsync_argv))
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|