17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
2249335bdeSbasabi
2349335bdeSbasabi /*
2449335bdeSbasabi * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
2549335bdeSbasabi * Use is subject to license terms.
2649335bdeSbasabi */
2749335bdeSbasabi
287c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
297c478bd9Sstevel@tonic-gate /* All Rights Reserved */
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337fc68ddfSAlbert Lee #include <sys/stat.h>
347c478bd9Sstevel@tonic-gate #include <stdio.h>
357c478bd9Sstevel@tonic-gate #include <userdefs.h>
367c478bd9Sstevel@tonic-gate #include <errno.h>
37ace1a5f1Sdp #include <strings.h>
387fc68ddfSAlbert Lee #include <stdlib.h>
397fc68ddfSAlbert Lee #include <sys/mntent.h>
407fc68ddfSAlbert Lee #include <sys/mnttab.h>
417fc68ddfSAlbert Lee #include <libzfs.h>
427fc68ddfSAlbert Lee #include <libgen.h>
437fc68ddfSAlbert Lee #include <limits.h>
447fc68ddfSAlbert Lee #include <deflt.h>
457fc68ddfSAlbert Lee
467fc68ddfSAlbert Lee #include "funcs.h"
477c478bd9Sstevel@tonic-gate #include "messages.h"
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate #define SBUFSZ 256
507c478bd9Sstevel@tonic-gate
517fc68ddfSAlbert Lee #define DEFAULT_USERADD "/etc/default/useradd"
527fc68ddfSAlbert Lee
537fc68ddfSAlbert Lee static int rm_homedir();
547fc68ddfSAlbert Lee static char *get_mnt_special();
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate static char cmdbuf[ SBUFSZ ]; /* buffer for system call */
577fc68ddfSAlbert Lee static char dhome[ PATH_MAX + 1 ]; /* buffer for dirname */
587fc68ddfSAlbert Lee static char bhome[ PATH_MAX + 1 ]; /* buffer for basename */
597fc68ddfSAlbert Lee static char pdir[ PATH_MAX + 1 ]; /* parent directory */
607fc68ddfSAlbert Lee static libzfs_handle_t *g_zfs = NULL;
617c478bd9Sstevel@tonic-gate
627c478bd9Sstevel@tonic-gate /*
637fc68ddfSAlbert Lee * Create a home directory and populate with files from skeleton
647fc68ddfSAlbert Lee * directory.
657c478bd9Sstevel@tonic-gate */
667c478bd9Sstevel@tonic-gate int
create_home(char * homedir,char * skeldir,uid_t uid,gid_t gid,int flags)677fc68ddfSAlbert Lee create_home(char *homedir, char *skeldir, uid_t uid, gid_t gid, int flags)
6849335bdeSbasabi /* home directory to create */
6949335bdeSbasabi /* skel directory to copy if indicated */
7049335bdeSbasabi /* uid of new user */
7149335bdeSbasabi /* group id of new user */
727fc68ddfSAlbert Lee /* miscellaneous flags */
737c478bd9Sstevel@tonic-gate {
747fc68ddfSAlbert Lee struct stat stbuf;
757fc68ddfSAlbert Lee char *dataset;
767fc68ddfSAlbert Lee char *dname, *bname, *rp;
777fc68ddfSAlbert Lee int created_fs = 0;
787fc68ddfSAlbert Lee
797fc68ddfSAlbert Lee rp = realpath(homedir, NULL);
807fc68ddfSAlbert Lee if (rp && (strcmp(rp, "/") == 0)) {
817c478bd9Sstevel@tonic-gate return (EX_HOMEDIR);
827c478bd9Sstevel@tonic-gate }
837c478bd9Sstevel@tonic-gate
847fc68ddfSAlbert Lee (void) strcpy(dhome, homedir);
857fc68ddfSAlbert Lee (void) strcpy(bhome, homedir);
867fc68ddfSAlbert Lee dname = dirname(dhome);
877fc68ddfSAlbert Lee bname = basename(bhome);
887fc68ddfSAlbert Lee (void) strcpy(pdir, dname);
897fc68ddfSAlbert Lee
907fc68ddfSAlbert Lee if ((stat(pdir, &stbuf) != 0) || !S_ISDIR(stbuf.st_mode)) {
917fc68ddfSAlbert Lee errmsg(M_OOPS, "access the parent directory", strerror(errno));
927fc68ddfSAlbert Lee return (EX_HOMEDIR);
937fc68ddfSAlbert Lee }
947fc68ddfSAlbert Lee
957fc68ddfSAlbert Lee if ((strcmp(stbuf.st_fstype, MNTTYPE_ZFS) == 0) &&
967fc68ddfSAlbert Lee (flags & MANAGE_ZFS)) {
977fc68ddfSAlbert Lee if (g_zfs == NULL)
987fc68ddfSAlbert Lee g_zfs = libzfs_init();
997fc68ddfSAlbert Lee if (g_zfs == NULL) {
1007fc68ddfSAlbert Lee errmsg(M_OOPS, "libzfs_init failure", strerror(errno));
1017fc68ddfSAlbert Lee return (EX_HOMEDIR);
1027fc68ddfSAlbert Lee }
1037fc68ddfSAlbert Lee if ((dataset = get_mnt_special(pdir, stbuf.st_fstype))
1047fc68ddfSAlbert Lee != NULL) {
105*40a5c998SMatthew Ahrens char nm[ZFS_MAX_DATASET_NAME_LEN];
1067fc68ddfSAlbert Lee zfs_handle_t *zhp;
1077fc68ddfSAlbert Lee
108*40a5c998SMatthew Ahrens (void) snprintf(nm, sizeof (nm), "%s/%s",
1097fc68ddfSAlbert Lee dataset, bname);
1107fc68ddfSAlbert Lee
1117fc68ddfSAlbert Lee if ((zfs_create(g_zfs, nm, ZFS_TYPE_FILESYSTEM, NULL)
1127fc68ddfSAlbert Lee != 0) ||
1137fc68ddfSAlbert Lee ((zhp = zfs_open(g_zfs, nm, ZFS_TYPE_FILESYSTEM)) ==
1147fc68ddfSAlbert Lee NULL)) {
1157fc68ddfSAlbert Lee errmsg(M_OOPS, "create the home directory",
1167fc68ddfSAlbert Lee libzfs_error_description(g_zfs));
1177fc68ddfSAlbert Lee libzfs_fini(g_zfs);
1187fc68ddfSAlbert Lee g_zfs = NULL;
1197fc68ddfSAlbert Lee return (EX_HOMEDIR);
1207fc68ddfSAlbert Lee }
1217fc68ddfSAlbert Lee
1227fc68ddfSAlbert Lee if (zfs_mount(zhp, NULL, 0) != 0) {
1237fc68ddfSAlbert Lee errmsg(M_OOPS, "mount the home directory",
1247fc68ddfSAlbert Lee libzfs_error_description(g_zfs));
1257fc68ddfSAlbert Lee (void) zfs_destroy(zhp, B_FALSE);
1267fc68ddfSAlbert Lee zfs_close(zhp);
1277fc68ddfSAlbert Lee libzfs_fini(g_zfs);
1287fc68ddfSAlbert Lee g_zfs = NULL;
1297fc68ddfSAlbert Lee return (EX_HOMEDIR);
1307fc68ddfSAlbert Lee }
1317fc68ddfSAlbert Lee
1327fc68ddfSAlbert Lee zfs_close(zhp);
1337fc68ddfSAlbert Lee
1347fc68ddfSAlbert Lee if (chmod(homedir,
1357fc68ddfSAlbert Lee S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0) {
1367fc68ddfSAlbert Lee errmsg(M_OOPS,
1377fc68ddfSAlbert Lee "change permissions of home directory",
1387fc68ddfSAlbert Lee strerror(errno));
1397fc68ddfSAlbert Lee libzfs_fini(g_zfs);
1407fc68ddfSAlbert Lee g_zfs = NULL;
1417fc68ddfSAlbert Lee return (EX_HOMEDIR);
1427fc68ddfSAlbert Lee }
1437fc68ddfSAlbert Lee
1447fc68ddfSAlbert Lee created_fs = 1;
1457fc68ddfSAlbert Lee } else {
1467fc68ddfSAlbert Lee errmsg(M_NO_ZFS_MOUNTPOINT, pdir);
1477fc68ddfSAlbert Lee }
1487fc68ddfSAlbert Lee }
1497fc68ddfSAlbert Lee
1507fc68ddfSAlbert Lee if (!created_fs) {
1517fc68ddfSAlbert Lee if (mkdir(homedir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
1527fc68ddfSAlbert Lee != 0) {
1537fc68ddfSAlbert Lee errmsg(M_OOPS, "create the home directory",
1547fc68ddfSAlbert Lee strerror(errno));
1557fc68ddfSAlbert Lee if (g_zfs != NULL) {
1567fc68ddfSAlbert Lee libzfs_fini(g_zfs);
1577fc68ddfSAlbert Lee g_zfs = NULL;
1587fc68ddfSAlbert Lee }
1597fc68ddfSAlbert Lee return (EX_HOMEDIR);
1607fc68ddfSAlbert Lee }
1617fc68ddfSAlbert Lee }
1627fc68ddfSAlbert Lee
1637c478bd9Sstevel@tonic-gate if (chown(homedir, uid, gid) != 0) {
1647c478bd9Sstevel@tonic-gate errmsg(M_OOPS, "change ownership of home directory",
165ace1a5f1Sdp strerror(errno));
1667fc68ddfSAlbert Lee if (g_zfs != NULL) {
1677fc68ddfSAlbert Lee libzfs_fini(g_zfs);
1687fc68ddfSAlbert Lee g_zfs = NULL;
1697fc68ddfSAlbert Lee }
1707c478bd9Sstevel@tonic-gate return (EX_HOMEDIR);
1717c478bd9Sstevel@tonic-gate }
1727c478bd9Sstevel@tonic-gate
1737fc68ddfSAlbert Lee if (skeldir != NULL) {
1747c478bd9Sstevel@tonic-gate /* copy the skel_dir into the home directory */
1757c478bd9Sstevel@tonic-gate (void) sprintf(cmdbuf, "cd %s && find . -print | cpio -pd %s",
1767c478bd9Sstevel@tonic-gate skeldir, homedir);
1777c478bd9Sstevel@tonic-gate
1787c478bd9Sstevel@tonic-gate if (system(cmdbuf) != 0) {
179ace1a5f1Sdp errmsg(M_OOPS, "copy skeleton directory into home "
180ace1a5f1Sdp "directory", strerror(errno));
1817fc68ddfSAlbert Lee (void) rm_homedir(homedir, flags);
1827fc68ddfSAlbert Lee if (g_zfs != NULL) {
1837fc68ddfSAlbert Lee libzfs_fini(g_zfs);
1847fc68ddfSAlbert Lee g_zfs = NULL;
1857fc68ddfSAlbert Lee }
1867c478bd9Sstevel@tonic-gate return (EX_HOMEDIR);
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gate /* make sure contents in the home dirctory have correct owner */
1907fc68ddfSAlbert Lee (void) sprintf(cmdbuf,
1917fc68ddfSAlbert Lee "cd %s && find . -exec chown %ld:%ld {} \\;",
1927fc68ddfSAlbert Lee homedir, uid, gid);
1937c478bd9Sstevel@tonic-gate if (system(cmdbuf) != 0) {
1947fc68ddfSAlbert Lee errmsg(M_OOPS,
1957fc68ddfSAlbert Lee "change owner and group of files home directory",
196ace1a5f1Sdp strerror(errno));
1977fc68ddfSAlbert Lee (void) rm_homedir(homedir, flags);
1987fc68ddfSAlbert Lee if (g_zfs != NULL) {
1997fc68ddfSAlbert Lee libzfs_fini(g_zfs);
2007fc68ddfSAlbert Lee g_zfs = NULL;
2017fc68ddfSAlbert Lee }
2027c478bd9Sstevel@tonic-gate return (EX_HOMEDIR);
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate }
2067fc68ddfSAlbert Lee if (g_zfs != NULL) {
2077fc68ddfSAlbert Lee libzfs_fini(g_zfs);
2087fc68ddfSAlbert Lee g_zfs = NULL;
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate return (EX_SUCCESS);
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate
2137c478bd9Sstevel@tonic-gate /* Remove a home directory structure */
21449335bdeSbasabi int
rm_homedir(char * dir,int flags)2157fc68ddfSAlbert Lee rm_homedir(char *dir, int flags)
2167c478bd9Sstevel@tonic-gate {
2177fc68ddfSAlbert Lee struct stat stbuf;
2187fc68ddfSAlbert Lee char *nm, *rp;
2197fc68ddfSAlbert Lee
2207fc68ddfSAlbert Lee rp = realpath(dir, NULL);
2217fc68ddfSAlbert Lee if (rp && (strcmp(rp, "/") == 0)) {
2227fc68ddfSAlbert Lee return (0);
2237fc68ddfSAlbert Lee }
2247fc68ddfSAlbert Lee
2257fc68ddfSAlbert Lee if ((stat(dir, &stbuf) != 0) || !S_ISDIR(stbuf.st_mode))
2267fc68ddfSAlbert Lee return (0);
2277fc68ddfSAlbert Lee
2287fc68ddfSAlbert Lee if ((strcmp(stbuf.st_fstype, MNTTYPE_ZFS) == 0) &&
2297fc68ddfSAlbert Lee (flags & MANAGE_ZFS)) {
2307fc68ddfSAlbert Lee if (g_zfs == NULL)
2317fc68ddfSAlbert Lee g_zfs = libzfs_init();
2327fc68ddfSAlbert Lee
2337fc68ddfSAlbert Lee if (g_zfs == NULL) {
2347fc68ddfSAlbert Lee errmsg(M_OOPS, "libzfs_init failure", strerror(errno));
2357fc68ddfSAlbert Lee return (EX_HOMEDIR);
2367fc68ddfSAlbert Lee }
2377fc68ddfSAlbert Lee
2387fc68ddfSAlbert Lee if ((nm = get_mnt_special(dir, stbuf.st_fstype)) != NULL) {
2397fc68ddfSAlbert Lee zfs_handle_t *zhp;
2407fc68ddfSAlbert Lee
2417fc68ddfSAlbert Lee if ((zhp = zfs_open(g_zfs, nm, ZFS_TYPE_FILESYSTEM))
2427fc68ddfSAlbert Lee != NULL) {
2437fc68ddfSAlbert Lee if ((zfs_unmount(zhp, NULL, 0) == 0) &&
2447fc68ddfSAlbert Lee (zfs_destroy(zhp, B_FALSE) == 0)) {
2457fc68ddfSAlbert Lee zfs_close(zhp);
2467fc68ddfSAlbert Lee libzfs_fini(g_zfs);
2477fc68ddfSAlbert Lee g_zfs = NULL;
2487fc68ddfSAlbert Lee return (0);
2497fc68ddfSAlbert Lee }
2507fc68ddfSAlbert Lee
2517fc68ddfSAlbert Lee errmsg(M_OOPS, "destroy the home directory",
2527fc68ddfSAlbert Lee libzfs_error_description(g_zfs));
2537fc68ddfSAlbert Lee
2547fc68ddfSAlbert Lee (void) zfs_mount(zhp, NULL, 0);
2557fc68ddfSAlbert Lee zfs_close(zhp);
2567fc68ddfSAlbert Lee
2577fc68ddfSAlbert Lee libzfs_fini(g_zfs);
2587fc68ddfSAlbert Lee g_zfs = NULL;
2597fc68ddfSAlbert Lee return (EX_HOMEDIR);
2607fc68ddfSAlbert Lee }
2617fc68ddfSAlbert Lee }
2627fc68ddfSAlbert Lee }
2637fc68ddfSAlbert Lee
2647c478bd9Sstevel@tonic-gate (void) sprintf(cmdbuf, "rm -rf %s", dir);
2657c478bd9Sstevel@tonic-gate
2667fc68ddfSAlbert Lee if (g_zfs != NULL) {
2677fc68ddfSAlbert Lee libzfs_fini(g_zfs);
2687fc68ddfSAlbert Lee g_zfs = NULL;
2697fc68ddfSAlbert Lee }
2707fc68ddfSAlbert Lee
2717c478bd9Sstevel@tonic-gate return (system(cmdbuf));
2727c478bd9Sstevel@tonic-gate }
2737fc68ddfSAlbert Lee
2747fc68ddfSAlbert Lee int
rm_files(char * homedir,char * user,int flags)2757fc68ddfSAlbert Lee rm_files(char *homedir, char *user, int flags)
2767fc68ddfSAlbert Lee {
2777fc68ddfSAlbert Lee if (rm_homedir(homedir, flags) != 0) {
2787fc68ddfSAlbert Lee errmsg(M_RMFILES);
2797fc68ddfSAlbert Lee return (EX_HOMEDIR);
2807fc68ddfSAlbert Lee }
2817fc68ddfSAlbert Lee
2827fc68ddfSAlbert Lee return (EX_SUCCESS);
2837fc68ddfSAlbert Lee }
2847fc68ddfSAlbert Lee
2857fc68ddfSAlbert Lee int
get_default_zfs_flags()2867fc68ddfSAlbert Lee get_default_zfs_flags()
2877fc68ddfSAlbert Lee {
2887fc68ddfSAlbert Lee int flags = 0;
2897fc68ddfSAlbert Lee
2907fc68ddfSAlbert Lee if (defopen(DEFAULT_USERADD) == 0) {
2917fc68ddfSAlbert Lee char *defptr;
2927fc68ddfSAlbert Lee
2937fc68ddfSAlbert Lee if ((defptr = defread(MANAGE_ZFS_OPT)) != NULL) {
2947fc68ddfSAlbert Lee char let = tolower(*defptr);
2957fc68ddfSAlbert Lee
2967fc68ddfSAlbert Lee switch (let) {
2977fc68ddfSAlbert Lee case 'y': /* yes */
2987fc68ddfSAlbert Lee flags |= MANAGE_ZFS;
2997fc68ddfSAlbert Lee case 'n': /* no */
3007fc68ddfSAlbert Lee break;
3017fc68ddfSAlbert Lee }
3027fc68ddfSAlbert Lee }
3037fc68ddfSAlbert Lee (void) defopen((char *)NULL);
3047fc68ddfSAlbert Lee }
3057fc68ddfSAlbert Lee return (flags);
3067fc68ddfSAlbert Lee }
3077fc68ddfSAlbert Lee
3087fc68ddfSAlbert Lee /* Get the name of a mounted filesytem */
3097fc68ddfSAlbert Lee char *
get_mnt_special(char * mountp,char * fstype)3107fc68ddfSAlbert Lee get_mnt_special(char *mountp, char *fstype)
3117fc68ddfSAlbert Lee {
3127fc68ddfSAlbert Lee struct mnttab entry, search;
3137fc68ddfSAlbert Lee char *special = NULL;
3147fc68ddfSAlbert Lee FILE *fp;
3157fc68ddfSAlbert Lee
3167fc68ddfSAlbert Lee search.mnt_special = search.mnt_mntopts = search.mnt_time = NULL;
3177fc68ddfSAlbert Lee search.mnt_mountp = mountp;
3187fc68ddfSAlbert Lee search.mnt_fstype = fstype;
3197fc68ddfSAlbert Lee
3207fc68ddfSAlbert Lee if ((fp = fopen(MNTTAB, "r")) != NULL) {
3217fc68ddfSAlbert Lee if (getmntany(fp, &entry, &search) == 0)
3227fc68ddfSAlbert Lee special = entry.mnt_special;
3237fc68ddfSAlbert Lee
3247fc68ddfSAlbert Lee (void) fclose(fp);
3257fc68ddfSAlbert Lee }
3267fc68ddfSAlbert Lee
3277fc68ddfSAlbert Lee return (special);
3287fc68ddfSAlbert Lee }
329