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 */ 227c478bd9Sstevel@tonic-gate 237c478bd9Sstevel@tonic-gate /* 2449335bdeSbasabi * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 257c478bd9Sstevel@tonic-gate * Use is subject to license terms. 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 2849335bdeSbasabi /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 2949335bdeSbasabi /* All Rights Reserved */ 3049335bdeSbasabi 3149335bdeSbasabi 327c478bd9Sstevel@tonic-gate #include <sys/types.h> 33*7fc68ddfSAlbert 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> 38*7fc68ddfSAlbert Lee #include <stdlib.h> 39*7fc68ddfSAlbert Lee #include <sys/mntent.h> 40*7fc68ddfSAlbert Lee #include <sys/mnttab.h> 41*7fc68ddfSAlbert Lee #include <libzfs.h> 42*7fc68ddfSAlbert Lee #include <libgen.h> 43*7fc68ddfSAlbert Lee #include <limits.h> 44*7fc68ddfSAlbert Lee #include <deflt.h> 45*7fc68ddfSAlbert Lee 46*7fc68ddfSAlbert Lee #include "funcs.h" 477c478bd9Sstevel@tonic-gate #include "messages.h" 487c478bd9Sstevel@tonic-gate 49*7fc68ddfSAlbert Lee #define SBUFSZ 256 50*7fc68ddfSAlbert Lee 51*7fc68ddfSAlbert Lee #define DEFAULT_USERADD "/etc/default/useradd" 527c478bd9Sstevel@tonic-gate 53*7fc68ddfSAlbert Lee static int rm_homedir(); 54*7fc68ddfSAlbert Lee static char *get_mnt_special(); 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate static char cmdbuf[ SBUFSZ ]; /* buffer for system call */ 57*7fc68ddfSAlbert Lee static char dhome[ PATH_MAX + 1 ]; /* buffer for dirname */ 58*7fc68ddfSAlbert Lee static char bhome[ PATH_MAX + 1 ]; /* buffer for basename */ 59*7fc68ddfSAlbert Lee static char pdir[ PATH_MAX + 1 ]; /* parent directory */ 60*7fc68ddfSAlbert Lee static libzfs_handle_t *g_zfs = NULL; 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate /* 63*7fc68ddfSAlbert Lee * Create a home directory and populate with files from skeleton 64*7fc68ddfSAlbert Lee * directory. 65*7fc68ddfSAlbert Lee */ 667c478bd9Sstevel@tonic-gate int 67*7fc68ddfSAlbert 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 */ 72*7fc68ddfSAlbert Lee /* miscellaneous flags */ 737c478bd9Sstevel@tonic-gate { 74*7fc68ddfSAlbert Lee struct stat stbuf; 75*7fc68ddfSAlbert Lee char *dataset; 76*7fc68ddfSAlbert Lee char *dname, *bname, *rp; 77*7fc68ddfSAlbert Lee int created_fs = 0; 78*7fc68ddfSAlbert Lee 79*7fc68ddfSAlbert Lee rp = realpath(homedir, NULL); 80*7fc68ddfSAlbert Lee if (rp && (strcmp(rp, "/") == 0)) { 81*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate 84*7fc68ddfSAlbert Lee (void) strcpy(dhome, homedir); 85*7fc68ddfSAlbert Lee (void) strcpy(bhome, homedir); 86*7fc68ddfSAlbert Lee dname = dirname(dhome); 87*7fc68ddfSAlbert Lee bname = basename(bhome); 88*7fc68ddfSAlbert Lee (void) strcpy(pdir, dname); 89*7fc68ddfSAlbert Lee 90*7fc68ddfSAlbert Lee if ((stat(pdir, &stbuf) != 0) || !S_ISDIR(stbuf.st_mode)) { 91*7fc68ddfSAlbert Lee errmsg(M_OOPS, "access the parent directory", strerror(errno)); 92*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 93*7fc68ddfSAlbert Lee } 94*7fc68ddfSAlbert Lee 95*7fc68ddfSAlbert Lee if ((strcmp(stbuf.st_fstype, MNTTYPE_ZFS) == 0) && 96*7fc68ddfSAlbert Lee (flags & MANAGE_ZFS)) { 97*7fc68ddfSAlbert Lee if (g_zfs == NULL) 98*7fc68ddfSAlbert Lee g_zfs = libzfs_init(); 99*7fc68ddfSAlbert Lee if (g_zfs == NULL) { 100*7fc68ddfSAlbert Lee errmsg(M_OOPS, "libzfs_init failure", strerror(errno)); 101*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 102*7fc68ddfSAlbert Lee } 103*7fc68ddfSAlbert Lee if ((dataset = get_mnt_special(pdir, stbuf.st_fstype)) 104*7fc68ddfSAlbert Lee != NULL) { 105*7fc68ddfSAlbert Lee char nm[ZFS_MAXNAMELEN]; 106*7fc68ddfSAlbert Lee zfs_handle_t *zhp; 107*7fc68ddfSAlbert Lee 108*7fc68ddfSAlbert Lee (void) snprintf(nm, ZFS_MAXNAMELEN, "%s/%s", 109*7fc68ddfSAlbert Lee dataset, bname); 110*7fc68ddfSAlbert Lee 111*7fc68ddfSAlbert Lee if ((zfs_create(g_zfs, nm, ZFS_TYPE_FILESYSTEM, NULL) 112*7fc68ddfSAlbert Lee != 0) || 113*7fc68ddfSAlbert Lee ((zhp = zfs_open(g_zfs, nm, ZFS_TYPE_FILESYSTEM)) == 114*7fc68ddfSAlbert Lee NULL)) { 115*7fc68ddfSAlbert Lee errmsg(M_OOPS, "create the home directory", 116*7fc68ddfSAlbert Lee libzfs_error_description(g_zfs)); 117*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 118*7fc68ddfSAlbert Lee g_zfs = NULL; 119*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 120*7fc68ddfSAlbert Lee } 121*7fc68ddfSAlbert Lee 122*7fc68ddfSAlbert Lee if (zfs_mount(zhp, NULL, 0) != 0) { 123*7fc68ddfSAlbert Lee errmsg(M_OOPS, "mount the home directory", 124*7fc68ddfSAlbert Lee libzfs_error_description(g_zfs)); 125*7fc68ddfSAlbert Lee (void) zfs_destroy(zhp, B_FALSE); 126*7fc68ddfSAlbert Lee zfs_close(zhp); 127*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 128*7fc68ddfSAlbert Lee g_zfs = NULL; 129*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 130*7fc68ddfSAlbert Lee } 131*7fc68ddfSAlbert Lee 132*7fc68ddfSAlbert Lee zfs_close(zhp); 133*7fc68ddfSAlbert Lee 134*7fc68ddfSAlbert Lee if (chmod(homedir, 135*7fc68ddfSAlbert Lee S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0) { 136*7fc68ddfSAlbert Lee errmsg(M_OOPS, 137*7fc68ddfSAlbert Lee "change permissions of home directory", 138*7fc68ddfSAlbert Lee strerror(errno)); 139*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 140*7fc68ddfSAlbert Lee g_zfs = NULL; 141*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 142*7fc68ddfSAlbert Lee } 143*7fc68ddfSAlbert Lee 144*7fc68ddfSAlbert Lee created_fs = 1; 145*7fc68ddfSAlbert Lee } else { 146*7fc68ddfSAlbert Lee errmsg(M_NO_ZFS_MOUNTPOINT, pdir); 147*7fc68ddfSAlbert Lee } 148*7fc68ddfSAlbert Lee } 149*7fc68ddfSAlbert Lee 150*7fc68ddfSAlbert Lee if (!created_fs) { 151*7fc68ddfSAlbert Lee if (mkdir(homedir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 152*7fc68ddfSAlbert Lee != 0) { 153*7fc68ddfSAlbert Lee errmsg(M_OOPS, "create the home directory", 154*7fc68ddfSAlbert Lee strerror(errno)); 155*7fc68ddfSAlbert Lee if (g_zfs != NULL) { 156*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 157*7fc68ddfSAlbert Lee g_zfs = NULL; 158*7fc68ddfSAlbert Lee } 159*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 160*7fc68ddfSAlbert Lee } 161*7fc68ddfSAlbert Lee } 162*7fc68ddfSAlbert Lee 163*7fc68ddfSAlbert Lee if (chown(homedir, uid, gid) != 0) { 164*7fc68ddfSAlbert Lee errmsg(M_OOPS, "change ownership of home directory", 165ace1a5f1Sdp strerror(errno)); 166*7fc68ddfSAlbert Lee if (g_zfs != NULL) { 167*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 168*7fc68ddfSAlbert Lee g_zfs = NULL; 169*7fc68ddfSAlbert Lee } 170*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate 173*7fc68ddfSAlbert Lee if (skeldir != NULL) { 1747c478bd9Sstevel@tonic-gate /* copy the skel_dir into the home directory */ 175*7fc68ddfSAlbert Lee (void) sprintf(cmdbuf, "cd %s && find . -print | cpio -pd %s", 1767c478bd9Sstevel@tonic-gate skeldir, homedir); 1777c478bd9Sstevel@tonic-gate 178*7fc68ddfSAlbert Lee if (system(cmdbuf) != 0) { 179ace1a5f1Sdp errmsg(M_OOPS, "copy skeleton directory into home " 180ace1a5f1Sdp "directory", strerror(errno)); 181*7fc68ddfSAlbert Lee (void) rm_homedir(homedir, flags); 182*7fc68ddfSAlbert Lee if (g_zfs != NULL) { 183*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 184*7fc68ddfSAlbert Lee g_zfs = NULL; 185*7fc68ddfSAlbert Lee } 186*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate /* make sure contents in the home dirctory have correct owner */ 190*7fc68ddfSAlbert Lee (void) sprintf(cmdbuf, 191*7fc68ddfSAlbert Lee "cd %s && find . -exec chown %ld:%ld {} \\;", 192*7fc68ddfSAlbert Lee homedir, uid, gid); 193*7fc68ddfSAlbert Lee if (system(cmdbuf) != 0) { 194*7fc68ddfSAlbert Lee errmsg(M_OOPS, 195*7fc68ddfSAlbert Lee "change owner and group of files home directory", 196ace1a5f1Sdp strerror(errno)); 197*7fc68ddfSAlbert Lee (void) rm_homedir(homedir, flags); 198*7fc68ddfSAlbert Lee if (g_zfs != NULL) { 199*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 200*7fc68ddfSAlbert Lee g_zfs = NULL; 201*7fc68ddfSAlbert Lee } 202*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 203*7fc68ddfSAlbert Lee } 204*7fc68ddfSAlbert Lee 205*7fc68ddfSAlbert Lee } 206*7fc68ddfSAlbert Lee if (g_zfs != NULL) { 207*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 208*7fc68ddfSAlbert Lee g_zfs = NULL; 209*7fc68ddfSAlbert Lee } 210*7fc68ddfSAlbert Lee return (EX_SUCCESS); 211*7fc68ddfSAlbert Lee } 212*7fc68ddfSAlbert Lee 213*7fc68ddfSAlbert Lee /* Remove a home directory structure */ 214*7fc68ddfSAlbert Lee int 215*7fc68ddfSAlbert Lee rm_homedir(char *dir, int flags) 216*7fc68ddfSAlbert Lee { 217*7fc68ddfSAlbert Lee struct stat stbuf; 218*7fc68ddfSAlbert Lee char *nm, *rp; 2197c478bd9Sstevel@tonic-gate 220*7fc68ddfSAlbert Lee rp = realpath(dir, NULL); 221*7fc68ddfSAlbert Lee if (rp && (strcmp(rp, "/") == 0)) { 222*7fc68ddfSAlbert Lee return (0); 223*7fc68ddfSAlbert Lee } 224*7fc68ddfSAlbert Lee 225*7fc68ddfSAlbert Lee if ((stat(dir, &stbuf) != 0) || !S_ISDIR(stbuf.st_mode)) 226*7fc68ddfSAlbert Lee return (0); 227*7fc68ddfSAlbert Lee 228*7fc68ddfSAlbert Lee if ((strcmp(stbuf.st_fstype, MNTTYPE_ZFS) == 0) && 229*7fc68ddfSAlbert Lee (flags & MANAGE_ZFS)) { 230*7fc68ddfSAlbert Lee if (g_zfs == NULL) 231*7fc68ddfSAlbert Lee g_zfs = libzfs_init(); 232*7fc68ddfSAlbert Lee 233*7fc68ddfSAlbert Lee if (g_zfs == NULL) { 234*7fc68ddfSAlbert Lee errmsg(M_OOPS, "libzfs_init failure", strerror(errno)); 235*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate 238*7fc68ddfSAlbert Lee if ((nm = get_mnt_special(dir, stbuf.st_fstype)) != NULL) { 239*7fc68ddfSAlbert Lee zfs_handle_t *zhp; 240*7fc68ddfSAlbert Lee 241*7fc68ddfSAlbert Lee if ((zhp = zfs_open(g_zfs, nm, ZFS_TYPE_FILESYSTEM)) 242*7fc68ddfSAlbert Lee != NULL) { 243*7fc68ddfSAlbert Lee if ((zfs_unmount(zhp, NULL, 0) == 0) && 244*7fc68ddfSAlbert Lee (zfs_destroy(zhp, B_FALSE) == 0)) { 245*7fc68ddfSAlbert Lee zfs_close(zhp); 246*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 247*7fc68ddfSAlbert Lee g_zfs = NULL; 248*7fc68ddfSAlbert Lee return (0); 249*7fc68ddfSAlbert Lee } 250*7fc68ddfSAlbert Lee 251*7fc68ddfSAlbert Lee errmsg(M_OOPS, "destroy the home directory", 252*7fc68ddfSAlbert Lee libzfs_error_description(g_zfs)); 253*7fc68ddfSAlbert Lee 254*7fc68ddfSAlbert Lee (void) zfs_mount(zhp, NULL, 0); 255*7fc68ddfSAlbert Lee zfs_close(zhp); 256*7fc68ddfSAlbert Lee 257*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 258*7fc68ddfSAlbert Lee g_zfs = NULL; 259*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 260*7fc68ddfSAlbert Lee } 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate } 263*7fc68ddfSAlbert Lee 264*7fc68ddfSAlbert Lee (void) sprintf(cmdbuf, "rm -rf %s", dir); 265*7fc68ddfSAlbert Lee 266*7fc68ddfSAlbert Lee if (g_zfs != NULL) { 267*7fc68ddfSAlbert Lee libzfs_fini(g_zfs); 268*7fc68ddfSAlbert Lee g_zfs = NULL; 269*7fc68ddfSAlbert Lee } 270*7fc68ddfSAlbert Lee 271*7fc68ddfSAlbert Lee return (system(cmdbuf)); 272*7fc68ddfSAlbert Lee } 273*7fc68ddfSAlbert Lee 274*7fc68ddfSAlbert Lee int 275*7fc68ddfSAlbert Lee rm_files(char *homedir, char *user, int flags) 276*7fc68ddfSAlbert Lee { 277*7fc68ddfSAlbert Lee if (rm_homedir(homedir, flags) != 0) { 278*7fc68ddfSAlbert Lee errmsg(M_RMFILES); 279*7fc68ddfSAlbert Lee return (EX_HOMEDIR); 280*7fc68ddfSAlbert Lee } 281*7fc68ddfSAlbert Lee 282*7fc68ddfSAlbert Lee return (EX_SUCCESS); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate 28549335bdeSbasabi int 286*7fc68ddfSAlbert Lee get_default_zfs_flags() 287*7fc68ddfSAlbert Lee { 288*7fc68ddfSAlbert Lee int flags = 0; 289*7fc68ddfSAlbert Lee 290*7fc68ddfSAlbert Lee if (defopen(DEFAULT_USERADD) == 0) { 291*7fc68ddfSAlbert Lee char *defptr; 292*7fc68ddfSAlbert Lee 293*7fc68ddfSAlbert Lee if ((defptr = defread(MANAGE_ZFS_OPT)) != NULL) { 294*7fc68ddfSAlbert Lee char let = tolower(*defptr); 295*7fc68ddfSAlbert Lee 296*7fc68ddfSAlbert Lee switch (let) { 297*7fc68ddfSAlbert Lee case 'y': /* yes */ 298*7fc68ddfSAlbert Lee flags |= MANAGE_ZFS; 299*7fc68ddfSAlbert Lee case 'n': /* no */ 300*7fc68ddfSAlbert Lee break; 301*7fc68ddfSAlbert Lee } 302*7fc68ddfSAlbert Lee } 303*7fc68ddfSAlbert Lee (void) defopen((char *)NULL); 304*7fc68ddfSAlbert Lee } 305*7fc68ddfSAlbert Lee return (flags); 306*7fc68ddfSAlbert Lee } 307*7fc68ddfSAlbert Lee 308*7fc68ddfSAlbert Lee /* Get the name of a mounted filesytem */ 309*7fc68ddfSAlbert Lee char * 310*7fc68ddfSAlbert Lee get_mnt_special(char *mountp, char *fstype) 3117c478bd9Sstevel@tonic-gate { 312*7fc68ddfSAlbert Lee struct mnttab entry, search; 313*7fc68ddfSAlbert Lee char *special = NULL; 314*7fc68ddfSAlbert Lee FILE *fp; 315*7fc68ddfSAlbert Lee 316*7fc68ddfSAlbert Lee search.mnt_special = search.mnt_mntopts = search.mnt_time = NULL; 317*7fc68ddfSAlbert Lee search.mnt_mountp = mountp; 318*7fc68ddfSAlbert Lee search.mnt_fstype = fstype; 319*7fc68ddfSAlbert Lee 320*7fc68ddfSAlbert Lee if ((fp = fopen(MNTTAB, "r")) != NULL) { 321*7fc68ddfSAlbert Lee if (getmntany(fp, &entry, &search) == 0) 322*7fc68ddfSAlbert Lee special = entry.mnt_special; 323*7fc68ddfSAlbert Lee 324*7fc68ddfSAlbert Lee (void) fclose(fp); 325*7fc68ddfSAlbert Lee } 326*7fc68ddfSAlbert Lee 327*7fc68ddfSAlbert Lee return (special); 3287c478bd9Sstevel@tonic-gate } 329