Print this page
Add libuserdefs and use in cmd/{oamuser,passwd}


  38 #include        <stdio.h>
  39 #include        <string.h>
  40 #include        <userdefs.h>
  41 #include        <user_attr.h>
  42 #include        <limits.h>
  43 #include        <stdlib.h>
  44 #include        <stddef.h>
  45 #include        <time.h>
  46 #include        <unistd.h>
  47 #include        "userdisp.h"
  48 #include        "funcs.h"
  49 #include        "messages.h"
  50 
  51 /* Print out a NL when the line gets too long */
  52 #define PRINTNL()       \
  53         if (outcount > 40) { \
  54                 outcount = 0; \
  55                 (void) fprintf(fptr, "\n"); \
  56         }
  57 
  58 #define SKIPWS(ptr)     while (*ptr && (*ptr == ' ' || *ptr == '\t')) ptr++
  59 
  60 static char *dup_to_nl(char *);
  61 
  62 static struct userdefs defaults = {
  63         DEFRID, DEFGROUP, DEFGNAME, DEFPARENT, DEFSKL,
  64         DEFSHL, DEFINACT, DEFEXPIRE, DEFAUTH, DEFPROF,
  65         DEFROLE, DEFPROJ, DEFPROJNAME, DEFLIMPRIV,
  66         DEFDFLTPRIV, DEFLOCK_AFTER_RETRIES
  67 };
  68 
  69 #define INT     0
  70 #define STR     1
  71 #define PROJID  2
  72 
  73 #define DEFOFF(field)           offsetof(struct userdefs, field)
  74 #define FIELD(up, pe, type)     (*(type *)((char *)(up) + (pe)->off))
  75 
  76 typedef struct parsent {
  77         const char *name;       /* deffoo= */
  78         const size_t nmsz;      /* length of def= string (excluding \0) */
  79         const int type;         /* type of entry */
  80         const ptrdiff_t off;    /* offset in userdefs structure */
  81         const char *uakey;      /* user_attr key, if defined */
  82 } parsent_t;
  83 
  84 static const parsent_t tab[] = {
  85         { GIDSTR,       sizeof (GIDSTR) - 1,    INT,    DEFOFF(defgroup) },
  86         { GNAMSTR,      sizeof (GNAMSTR) - 1,   STR,    DEFOFF(defgname) },
  87         { PARSTR,       sizeof (PARSTR) - 1,    STR,    DEFOFF(defparent) },
  88         { SKLSTR,       sizeof (SKLSTR) - 1,    STR,    DEFOFF(defskel) },
  89         { SHELLSTR,     sizeof (SHELLSTR) - 1,  STR,    DEFOFF(defshell) },
  90         { INACTSTR,     sizeof (INACTSTR) - 1,  INT,    DEFOFF(definact) },
  91         { EXPIRESTR,    sizeof (EXPIRESTR) - 1, STR,    DEFOFF(defexpire) },
  92         { AUTHSTR,      sizeof (AUTHSTR) - 1,   STR,    DEFOFF(defauth),
  93                 USERATTR_AUTHS_KW },
  94         { ROLESTR,      sizeof (ROLESTR) - 1,   STR,    DEFOFF(defrole),
  95                 USERATTR_ROLES_KW },
  96         { PROFSTR,      sizeof (PROFSTR) - 1,   STR,    DEFOFF(defprof),
  97                 USERATTR_PROFILES_KW },
  98         { PROJSTR,      sizeof (PROJSTR) - 1,   PROJID, DEFOFF(defproj) },
  99         { PROJNMSTR,    sizeof (PROJNMSTR) - 1, STR,    DEFOFF(defprojname) },
 100         { LIMPRSTR,     sizeof (LIMPRSTR) - 1,  STR,    DEFOFF(deflimpriv),
 101                 USERATTR_LIMPRIV_KW },
 102         { DFLTPRSTR,    sizeof (DFLTPRSTR) - 1, STR,    DEFOFF(defdfltpriv),
 103                 USERATTR_DFLTPRIV_KW },
 104         { LOCK_AFTER_RETRIESSTR,        sizeof (LOCK_AFTER_RETRIESSTR) - 1,
 105                 STR,    DEFOFF(deflock_after_retries),
 106                 USERATTR_LOCK_AFTER_RETRIES_KW },
 107 };
 108 
 109 #define NDEF    (sizeof (tab) / sizeof (parsent_t))
 110 
 111 FILE *defptr;           /* default file - fptr */
 112 
 113 static const parsent_t *
 114 scan(char **start_p)
 115 {
 116         static int ind = NDEF - 1;
 117         char *cur_p = *start_p;
 118         int lastind = ind;
 119 
 120         if (!*cur_p || *cur_p == '\n' || *cur_p == '#')
 121                 return (NULL);
 122 
 123         /*
 124          * The magic in this loop is remembering the last index when
 125          * reentering the function; the entries above are also used to
 126          * order the output to the default file.
 127          */
 128         do {
 129                 ind++;
 130                 ind %= NDEF;
 131 
 132                 if (strncmp(cur_p, tab[ind].name, tab[ind].nmsz) == 0) {
 133                         *start_p = cur_p + tab[ind].nmsz;
 134                         return (&tab[ind]);
 135                 }
 136         } while (ind != lastind);
 137 
 138         return (NULL);
 139 }
 140 
 141 /*
 142  * getusrdef - access the user defaults file.  If it doesn't exist,
 143  *              then returns default values of (values in userdefs.h):
 144  *              defrid = 100
 145  *              defgroup = 1
 146  *              defgname = other
 147  *              defparent = /home
 148  *              defskel = /usr/sadm/skel
 149  *              defshell = /bin/sh
 150  *              definact = 0
 151  *              defexpire = 0
 152  *              defauth = 0
 153  *              defprof = 0
 154  *              defrole = 0
 155  *
 156  *      If getusrdef() is unable to access the defaults file, it
 157  *      returns a NULL pointer.
 158  *
 159  *      If user defaults file exists, then getusrdef uses values
 160  *  in it to override the above values.
 161  */
 162 
 163 struct userdefs *
 164 getusrdef(char *usertype)
 165 {
 166         char instr[512], *ptr;
 167         const parsent_t *pe;
 168 
 169         if (is_role(usertype)) {
 170                 if ((defptr = fopen(DEFROLEFILE, "r")) == NULL) {
 171                         defaults.defshell = DEFROLESHL;
 172                         defaults.defprof = DEFROLEPROF;
 173                         return (&defaults);
 174                 }
 175         } else {
 176                 if ((defptr = fopen(DEFFILE, "r")) == NULL)
 177                         return (&defaults);
 178         }
 179 
 180         while (fgets(instr, sizeof (instr), defptr) != NULL) {
 181                 ptr = instr;
 182 
 183                 SKIPWS(ptr);
 184 
 185                 if (*ptr == '#')
 186                         continue;
 187 
 188                 pe = scan(&ptr);
 189 
 190                 if (pe != NULL) {
 191                         switch (pe->type) {
 192                         case INT:
 193                                 FIELD(&defaults, pe, int) =
 194                                         (int)strtol(ptr, NULL, 10);
 195                                 break;
 196                         case PROJID:
 197                                 FIELD(&defaults, pe, projid_t) =
 198                                         (projid_t)strtol(ptr, NULL, 10);
 199                                 break;
 200                         case STR:
 201                                 FIELD(&defaults, pe, char *) = dup_to_nl(ptr);
 202                                 break;
 203                         }
 204                 }
 205         }
 206 
 207         (void) fclose(defptr);
 208 
 209         return (&defaults);
 210 }
 211 
 212 static char *
 213 dup_to_nl(char *from)
 214 {
 215         char *res = strdup(from);
 216 
 217         char *p = strchr(res, '\n');
 218         if (p)
 219                 *p = '\0';
 220 
 221         return (res);
 222 }
 223 
 224 void
 225 dispusrdef(FILE *fptr, unsigned flags, char *usertype)
 226 {
 227         struct userdefs *deflts = getusrdef(usertype);
 228         int outcount = 0;
 229 
 230         /* Print out values */
 231 
 232         if (flags & D_GROUP) {
 233                 outcount += fprintf(fptr, "group=%s,%ld  ",
 234                         deflts->defgname, deflts->defgroup);
 235                 PRINTNL();
 236         }
 237 
 238         if (flags & D_PROJ) {
 239                 outcount += fprintf(fptr, "project=%s,%ld  ",
 240                     deflts->defprojname, deflts->defproj);
 241                 PRINTNL();
 242         }
 243 


 298                         deflts->defdfltpriv);
 299                 PRINTNL();
 300         }
 301 
 302         if (flags & D_LOCK) {
 303                 outcount += fprintf(fptr, "lock_after_retries=%s  ",
 304                     deflts->deflock_after_retries);
 305         }
 306 
 307         if (outcount > 0)
 308                 (void) fprintf(fptr, "\n");
 309 }
 310 
 311 /*
 312  * putusrdef -
 313  *      changes default values in defadduser file
 314  */
 315 int
 316 putusrdef(struct userdefs *defs, char *usertype)
 317 {
 318         time_t timeval;         /* time value from time */
 319         int i;
 320         ptrdiff_t skip;
 321         char *hdr;
 322 
 323         /*
 324          * file format is:
 325          * #<tab>Default values for adduser.  Changed mm/dd/yy hh:mm:ss.
 326          * defgroup=m   (m=default group id)
 327          * defgname=str1        (str1=default group name)
 328          * defparent=str2       (str2=default base directory)
 329          * definactive=x        (x=default inactive)
 330          * defexpire=y          (y=default expire)
 331          * defproj=z            (z=numeric project id)
 332          * defprojname=str3     (str3=default project name)
 333          * ... etc ...
 334          */
 335 
 336         if (is_role(usertype)) {
 337                 if ((defptr = fopen(DEFROLEFILE, "w")) == NULL) {
 338                         errmsg(M_FAILED);
 339                         return (EX_UPDATE);
 340                 }
 341         } else {
 342                 if ((defptr = fopen(DEFFILE, "w")) == NULL) {


 343                         errmsg(M_FAILED);
 344                         return (EX_UPDATE);
 345                 }
 346         }
 347 
 348         if (lockf(fileno(defptr), F_LOCK, 0) != 0) {
 349                 /* print error if can't lock whole of DEFFILE */
 350                 errmsg(M_UPDATE, "created");
 351                 return (EX_UPDATE);
 352         }

 353 
 354         if (is_role(usertype)) {
 355                 /* If it's a role, we must skip the defrole field */
 356                 skip = offsetof(struct userdefs, defrole);
 357                 hdr = FHEADER_ROLE;
 358         } else {
 359                 skip = -1;
 360                 hdr = FHEADER;
 361         }
 362 
 363         /* get time */
 364         timeval = time(NULL);
 365 
 366         /* write it to file */
 367         if (fprintf(defptr, "%s%s\n", hdr, ctime(&timeval)) <= 0) {
 368                 errmsg(M_UPDATE, "created");
 369                 return (EX_UPDATE);
 370         }
 371 
 372         for (i = 0; i < NDEF; i++) {
 373                 int res = 0;
 374 
 375                 if (tab[i].off == skip)
 376                         continue;
 377 
 378                 switch (tab[i].type) {
 379                 case INT:
 380                         res = fprintf(defptr, "%s%d\n", tab[i].name,
 381                                         FIELD(defs, &tab[i], int));
 382                         break;
 383                 case STR:
 384                         res = fprintf(defptr, "%s%s\n", tab[i].name,
 385                                         FIELD(defs, &tab[i], char *));
 386                         break;
 387                 case PROJID:
 388                         res = fprintf(defptr, "%s%d\n", tab[i].name,
 389                                         (int)FIELD(defs, &tab[i], projid_t));
 390                         break;
 391                 }
 392 
 393                 if (res <= 0) {
 394                         errmsg(M_UPDATE, "created");
 395                         return (EX_UPDATE);
 396                 }
 397         }
 398 
 399         (void) lockf(fileno(defptr), F_ULOCK, 0);
 400         (void) fclose(defptr);
 401 
 402         return (EX_SUCCESS);
 403 }
 404 
 405 /* Export command line keys to defaults for useradd -D */
 406 void
 407 update_def(struct userdefs *ud)
 408 {
 409         int i;
 410 
 411         for (i = 0; i < NDEF; i++) {
 412                 char *val;
 413                 if (tab[i].uakey != NULL &&
 414                     (val = getsetdefval(tab[i].uakey, NULL)) != NULL)
 415                         FIELD(ud, &tab[i], char *) = val;
 416         }
 417 }
 418 
 419 /* Import default keys for ordinary useradd */
 420 void
 421 import_def(struct userdefs *ud)
 422 {
 423         int i;
 424 
 425         for (i = 0; i < NDEF; i++) {
 426                 if (tab[i].uakey != NULL && tab[i].type == STR) {
 427                         char *val = FIELD(ud, &tab[i], char *);
 428                         if (val == getsetdefval(tab[i].uakey, val))
 429                                 nkeys ++;
 430                 }
 431         }
 432 }


  38 #include        <stdio.h>
  39 #include        <string.h>
  40 #include        <userdefs.h>
  41 #include        <user_attr.h>
  42 #include        <limits.h>
  43 #include        <stdlib.h>
  44 #include        <stddef.h>
  45 #include        <time.h>
  46 #include        <unistd.h>
  47 #include        "userdisp.h"
  48 #include        "funcs.h"
  49 #include        "messages.h"
  50 
  51 /* Print out a NL when the line gets too long */
  52 #define PRINTNL()       \
  53         if (outcount > 40) { \
  54                 outcount = 0; \
  55                 (void) fprintf(fptr, "\n"); \
  56         }
  57 



















































































  58 /*
  59  * getusrdef - get the user defaults file for the type of
  60  * user entry (user or role).  See libuserdefs

















  61  */
  62 
  63 struct userdefs *
  64 getusrdef(char *usertype)
  65 {
  66         struct userdefs *ud;

  67 
  68         if (is_role(usertype))
  69                 ud = _get_roledefs();
  70         else
  71                 ud = _get_userdefs();






  72 
  73         return (ud);





























  74 }
  75 












  76 void
  77 dispusrdef(FILE *fptr, unsigned flags, char *usertype)
  78 {
  79         struct userdefs *deflts = getusrdef(usertype);
  80         int outcount = 0;
  81 
  82         /* Print out values */
  83 
  84         if (flags & D_GROUP) {
  85                 outcount += fprintf(fptr, "group=%s,%ld  ",
  86                     deflts->defgname, deflts->defgroup);
  87                 PRINTNL();
  88         }
  89 
  90         if (flags & D_PROJ) {
  91                 outcount += fprintf(fptr, "project=%s,%ld  ",
  92                     deflts->defprojname, deflts->defproj);
  93                 PRINTNL();
  94         }
  95 


 150                     deflts->defdfltpriv);
 151                 PRINTNL();
 152         }
 153 
 154         if (flags & D_LOCK) {
 155                 outcount += fprintf(fptr, "lock_after_retries=%s  ",
 156                     deflts->deflock_after_retries);
 157         }
 158 
 159         if (outcount > 0)
 160                 (void) fprintf(fptr, "\n");
 161 }
 162 
 163 /*
 164  * putusrdef -
 165  *      changes default values in defadduser file
 166  */
 167 int
 168 putusrdef(struct userdefs *defs, char *usertype)
 169 {
 170         FILE *fp = NULL;        /* default file - fptr */
 171         boolean_t locked = B_FALSE;
 172         int res;
 173         int ex = EX_UPDATE;
 174 













 175         if (is_role(usertype)) {
 176                 fp = fopen(DEFROLEFILE, "w");



 177         } else {
 178                 fp = fopen(DEFFILE, "w");
 179         }
 180         if (fp == NULL) {
 181                 errmsg(M_FAILED);
 182                 goto out;
 183         }

 184 
 185         if (lockf(fileno(fp), F_LOCK, 0) != 0) {
 186                 /* print error if can't lock whole of DEFFILE */
 187                 errmsg(M_UPDATE, "created");
 188                 goto out;
 189         }
 190         locked = B_TRUE;
 191 
 192         if (is_role(usertype)) {
 193                 res = fwrite_roledefs(fp, defs);


 194         } else {
 195                 res = fwrite_userdefs(fp, defs);

 196         }































 197         if (res <= 0) {
 198                 errmsg(M_UPDATE, "created");
 199                 goto out;
 200         }
 201         ex = EX_SUCCESS;
 202 
 203 out:
 204         if (fp != NULL) {
 205                 if (locked)
 206                         (void) lockf(fileno(fp), F_ULOCK, 0);
 207                 (void) fclose(fp);












 208         }

 209 
 210         return (ex);












 211 }