Print this page
293 useradd/del/mod should be ZFS-aware

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/oamuser/user/homedir.c
          +++ new/usr/src/cmd/oamuser/user/homedir.c
↓ open down ↓ 21 lines elided ↑ open up ↑
  22   22  
  23   23  /*
  24   24   * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  25   25   * Use is subject to license terms.
  26   26   */
  27   27  
  28   28  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  29   29  /*        All Rights Reserved   */
  30   30  
  31   31  
  32      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  33      -
  34   32  #include <sys/types.h>
       33 +#include <sys/stat.h>
  35   34  #include <stdio.h>
  36   35  #include <userdefs.h>
  37   36  #include <errno.h>
  38   37  #include <strings.h>
       38 +#include <sys/mntent.h>
       39 +#include <sys/mnttab.h>
       40 +#include <libzfs.h>
       41 +#include <libgen.h>
       42 +#include <limits.h>
       43 +#include <deflt.h>
       44 +
       45 +#include "funcs.h"
  39   46  #include "messages.h"
  40   47  
  41      -#define         SBUFSZ  256
       48 +#define SBUFSZ  256
  42   49  
  43      -extern int rm_homedir();
       50 +#define DEFAULT_USERADD "/etc/default/useradd"
       51 +
       52 +static int rm_homedir();
       53 +static char *get_mnt_special();
  44   54  
  45   55  static char cmdbuf[ SBUFSZ ];   /* buffer for system call */
       56 +static char dhome[ PATH_MAX + 1 ]; /* buffer for dirname */
       57 +static char bhome[ PATH_MAX + 1 ]; /* buffer for basename */
       58 +static char pdir[ PATH_MAX + 1 ]; /* parent directory */
       59 +static libzfs_handle_t *g_zfs = NULL;
  46   60  
  47   61  /*
  48      -        Create a home directory and populate with files from skeleton
  49      -        directory.
  50      -*/
       62 + * Create a home directory and populate with files from skeleton
       63 + * directory.
       64 + */
  51   65  int
  52      -create_home(char *homedir, char *skeldir, uid_t uid, gid_t gid)
       66 +create_home(char *homedir, char *skeldir, uid_t uid, gid_t gid, int flags)
  53   67                  /* home directory to create */
  54   68                  /* skel directory to copy if indicated */
  55   69                  /* uid of new user */
  56   70                  /* group id of new user */
       71 +                /* miscellaneous flags */
  57   72  {
  58      -        if( mkdir(homedir, 0775) != 0 ) {
  59      -                errmsg(M_OOPS, "create the home directory", strerror(errno));
  60      -                return( EX_HOMEDIR );
       73 +        struct stat stbuf;
       74 +        char *dataset;
       75 +        char *dname, *bname;
       76 +
       77 +        if (g_zfs == NULL)
       78 +                g_zfs = libzfs_init();
       79 +
       80 +        (void) strcpy(dhome, homedir);
       81 +        (void) strcpy(bhome, homedir);
       82 +        dname = dirname(dhome);
       83 +        bname = basename(bhome);
       84 +        (void) strcpy(pdir, dname);
       85 +
       86 +        if ((stat(pdir, &stbuf) != 0) || !S_ISDIR(stbuf.st_mode)) {
       87 +                errmsg(M_OOPS, "access the parent directory", strerror(errno));
       88 +                if (g_zfs) {
       89 +                        libzfs_fini(g_zfs);
       90 +                        g_zfs = NULL;
       91 +                }
       92 +                return (EX_HOMEDIR);
  61   93          }
  62   94  
  63      -        if( chown(homedir, uid, gid) != 0 ) {
  64      -                errmsg(M_OOPS, "change ownership of home directory", 
       95 +        if ((strcmp(stbuf.st_fstype, MNTTYPE_ZFS) == 0) &&
       96 +            (g_zfs != NULL) && (flags & CHANGE_ZFS_FS) &&
       97 +            ((dataset = get_mnt_special(pdir, stbuf.st_fstype)) != NULL)) {
       98 +                char nm[ZFS_MAXNAMELEN];
       99 +                zfs_handle_t *zhp;
      100 +
      101 +                (void) snprintf(nm, ZFS_MAXNAMELEN, "%s/%s", dataset, bname);
      102 +
      103 +                if ((zfs_create(g_zfs, nm, ZFS_TYPE_FILESYSTEM, NULL) != 0) ||
      104 +                    ((zhp = zfs_open(g_zfs, nm, ZFS_TYPE_FILESYSTEM)) ==
      105 +                    NULL)) {
      106 +                        errmsg(M_OOPS, "create the home directory",
      107 +                            libzfs_error_description(g_zfs));
      108 +                        libzfs_fini(g_zfs);
      109 +                        g_zfs = NULL;
      110 +                        return (EX_HOMEDIR);
      111 +                }
      112 +
      113 +                if (zfs_mount(zhp, NULL, 0) != 0) {
      114 +                        errmsg(M_OOPS, "mount the home directory",
      115 +                            libzfs_error_description(g_zfs));
      116 +                        (void) zfs_destroy(zhp, B_FALSE);
      117 +                        zfs_close(zhp);
      118 +                        libzfs_fini(g_zfs);
      119 +                        g_zfs = NULL;
      120 +                        return (EX_HOMEDIR);
      121 +                }
      122 +
      123 +                zfs_close(zhp);
      124 +
      125 +                if (chmod(homedir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
      126 +                        != 0) {
      127 +                        errmsg(M_OOPS, "change permissions of home directory",
      128 +                            strerror(errno));
      129 +                        libzfs_fini(g_zfs);
      130 +                        g_zfs = NULL;
      131 +                        return (EX_HOMEDIR);
      132 +                }
      133 +        } else {
      134 +                if (mkdir(homedir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
      135 +                        != 0) {
      136 +                        errmsg(M_OOPS, "create the home directory",
      137 +                            strerror(errno));
      138 +                        if (g_zfs) {
      139 +                                libzfs_fini(g_zfs);
      140 +                                g_zfs = NULL;
      141 +                        }
      142 +                        return (EX_HOMEDIR);
      143 +                }
      144 +        }
      145 +
      146 +        if (chown(homedir, uid, gid) != 0) {
      147 +                errmsg(M_OOPS, "change ownership of home directory",
  65  148                      strerror(errno));
  66      -                return( EX_HOMEDIR );
      149 +                if (g_zfs) {
      150 +                        libzfs_fini(g_zfs);
      151 +                        g_zfs = NULL;
      152 +                }
      153 +                return (EX_HOMEDIR);
  67  154          }
  68  155  
  69      -        if(skeldir) {
      156 +        if (skeldir) {
  70  157                  /* copy the skel_dir into the home directory */
  71      -                (void) sprintf( cmdbuf, "cd %s && find . -print | cpio -pd %s",
      158 +                (void) sprintf(cmdbuf, "cd %s && find . -print | cpio -pd %s",
  72  159                          skeldir, homedir);
  73  160  
  74      -                if( system( cmdbuf ) != 0 ) {
      161 +                if (system(cmdbuf) != 0) {
  75  162                          errmsg(M_OOPS, "copy skeleton directory into home "
  76  163                              "directory", strerror(errno));
  77      -                        (void) rm_homedir( homedir );
  78      -                        return( EX_HOMEDIR );
      164 +                        (void) rm_homedir(homedir, flags);
      165 +                        if (g_zfs) {
      166 +                                libzfs_fini(g_zfs);
      167 +                                g_zfs = NULL;
      168 +                        }
      169 +                        return (EX_HOMEDIR);
  79  170                  }
  80  171  
  81  172                  /* make sure contents in the home dirctory have correct owner */
  82      -                (void) sprintf( cmdbuf,"cd %s && find . -exec chown %ld {} \\;",
  83      -                        homedir, uid );
  84      -                if( system( cmdbuf ) != 0) {
  85      -                        errmsg(M_OOPS, "change owner of files home directory",
      173 +                (void) sprintf(cmdbuf,
      174 +                    "cd %s && find . -exec chown %ld:%ld {} \\;",
      175 +                    homedir, uid, gid);
      176 +                if (system(cmdbuf) != 0) {
      177 +                        errmsg(M_OOPS,
      178 +                            "change owner and group of files home directory",
  86  179                              strerror(errno));
  87      -
  88      -                        (void) rm_homedir( homedir );
  89      -                        return( EX_HOMEDIR );
      180 +                        (void) rm_homedir(homedir, flags);
      181 +                        if (g_zfs) {
      182 +                                libzfs_fini(g_zfs);
      183 +                                g_zfs = NULL;
      184 +                        }
      185 +                        return (EX_HOMEDIR);
  90  186                  }
  91  187  
  92      -                /* and group....... */
  93      -                (void) sprintf( cmdbuf, "cd %s && find . -exec chgrp %ld {} \\;",
  94      -                        homedir, gid );
  95      -                if( system( cmdbuf ) != 0) {
  96      -                        errmsg(M_OOPS, "change group of files home directory",
  97      -                            strerror(errno));
  98      -                        (void) rm_homedir( homedir );
  99      -                        return( EX_HOMEDIR );
 100      -                }
 101  188          }
 102      -        return( EX_SUCCESS );
      189 +        if (g_zfs) {
      190 +                libzfs_fini(g_zfs);
      191 +                g_zfs = NULL;
      192 +        }
      193 +        return (EX_SUCCESS);
 103  194  }
 104  195  
 105  196  /* Remove a home directory structure */
 106  197  int
 107      -rm_homedir(char *dir)
      198 +rm_homedir(char *dir, int flags)
 108  199  {
 109      -        (void) sprintf( cmdbuf, "rm -rf %s", dir );
 110      -                
 111      -        return( system( cmdbuf ) );
      200 +        struct stat stbuf;
      201 +        char *nm;
      202 +
      203 +        if ((stat(dir, &stbuf) != 0) || !S_ISDIR(stbuf.st_mode))
      204 +                return (0);
      205 +
      206 +        if (g_zfs == NULL)
      207 +                g_zfs = libzfs_init();
      208 +
      209 +        if ((strcmp(stbuf.st_fstype, MNTTYPE_ZFS) == 0) &&
      210 +            (flags & CHANGE_ZFS_FS) &&
      211 +            (g_zfs != NULL) &&
      212 +            ((nm = get_mnt_special(dir, stbuf.st_fstype)) != NULL)) {
      213 +                zfs_handle_t *zhp;
      214 +
      215 +                if ((zhp = zfs_open(g_zfs, nm, ZFS_TYPE_FILESYSTEM)) != NULL) {
      216 +                        if ((zfs_unmount(zhp, NULL, 0) == 0) &&
      217 +                            (zfs_destroy(zhp, B_FALSE) == 0)) {
      218 +                                zfs_close(zhp);
      219 +                                return (0);
      220 +                        }
      221 +
      222 +                        (void) zfs_mount(zhp, NULL, 0);
      223 +                        zfs_close(zhp);
      224 +                }
      225 +        }
      226 +
      227 +        (void) sprintf(cmdbuf, "rm -rf %s", dir);
      228 +
      229 +        return (system(cmdbuf));
      230 +}
      231 +
      232 +int
      233 +rm_files(char *homedir, char *user, int flags)
      234 +{
      235 +        if (rm_homedir(homedir, flags) != 0) {
      236 +                errmsg(M_RMFILES);
      237 +                return (EX_HOMEDIR);
      238 +        }
      239 +
      240 +        return (EX_SUCCESS);
      241 +}
      242 +
      243 +int
      244 +get_default_zfs_flags()
      245 +{
      246 +        int flags = 0;
      247 +
      248 +        if (defopen(DEFAULT_USERADD) == 0) {
      249 +                char *defptr;
      250 +
      251 +                if ((defptr = defread(CHANGE_ZFS_FS_OPT)) != NULL) {
      252 +                        char let = tolower(*defptr);
      253 +
      254 +                        switch (let) {
      255 +                                case 'y':       /* yes */
      256 +                                        flags |= CHANGE_ZFS_FS;
      257 +                                case 'n':       /* no */
      258 +                                        break;
      259 +                        }
      260 +                }
      261 +                (void) defopen((char *)NULL);
      262 +        }
      263 +        return (flags);
      264 +}
      265 +
      266 +/* Get the name of a mounted filesytem */
      267 +char *
      268 +get_mnt_special(char *mountp, char *fstype)
      269 +{
      270 +        struct mnttab entry, search;
      271 +        char *special = NULL;
      272 +        FILE *fp;
      273 +
      274 +        search.mnt_special = search.mnt_mntopts = search.mnt_time = NULL;
      275 +        search.mnt_mountp = mountp;
      276 +        search.mnt_fstype = fstype;
      277 +
      278 +        if ((fp = fopen(MNTTAB, "r")) != NULL) {
      279 +                if (getmntany(fp, &entry, &search) == 0)
      280 +                        special = entry.mnt_special;
      281 +
      282 +                (void) fclose(fp);
      283 +        }
      284 +
      285 +        return (special);
 112  286  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX