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 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 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 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 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 * 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