Print this page
    
2989 Eliminate use of LOGNAME_MAX in ON
1166 useradd have warning with name more 8 chars
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/oamuser/user/usermod.c
          +++ new/usr/src/cmd/oamuser/user/usermod.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  
    | 
      ↓ open down ↓ | 
    11 lines elided | 
    
      ↑ open up ↑ | 
  
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
       22 + * Copyright (c) 2013 Gary Mills
       23 + *
  22   24   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23   25   * Use is subject to license terms.
  24   26   */
  25   27  
  26   28  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  27   29  /*        All Rights Reserved   */
  28   30  
  29   31  
  30   32  
  31   33  #include <sys/types.h>
  32   34  #include <sys/stat.h>
  33   35  #include <sys/param.h>
  34   36  #include <stdio.h>
  35   37  #include <stdlib.h>
  36   38  #include <ctype.h>
  37   39  #include <limits.h>
  38   40  #include <string.h>
  39   41  #include <userdefs.h>
  40   42  #include <user_attr.h>
  41   43  #include <nss_dbdefs.h>
  42   44  #include <errno.h>
  43   45  #include <project.h>
  44   46  #include "users.h"
  45   47  #include "messages.h"
  46   48  #include "funcs.h"
  47   49  
  48   50  /*
  49   51   *  usermod [-u uid [-o] | -g group | -G group [[,group]...] | -d dir [-m]
  50   52   *              | -s shell | -c comment | -l new_logname]
  51   53   *              | -f inactive | -e expire ]
  52   54   *              [ -A authorization [, authorization ...]]
  53   55   *              [ -P profile [, profile ...]]
  54   56   *              [ -R role [, role ...]]
  55   57   *              [ -K key=value ]
  56   58   *              [ -p project [, project]] login
  57   59   *
  58   60   *      This command adds new user logins to the system.  Arguments are:
  59   61   *
  60   62   *      uid - an integer less than MAXUID
  61   63   *      group - an existing group's integer ID or char string name
  62   64   *      dir - a directory
  63   65   *      shell - a program to be used as a shell
  64   66   *      comment - any text string
  65   67   *      skel_dir - a directory
  66   68   *      base_dir - a directory
  67   69   *      rid - an integer less than 2**16 (USHORT)
  68   70   *      login - a string of printable chars except colon (:)
  69   71   *      inactive - number of days a login maybe inactive before it is locked
  70   72   *      expire - date when a login is no longer valid
  71   73   *      authorization - One or more comma separated authorizations defined
  72   74   *                      in auth_attr(4).
  73   75   *      profile - One or more comma separated execution profiles defined
  74   76   *                in prof_attr(4)
  75   77   *      role - One or more comma-separated role names defined in user_attr(4)
  76   78   *      key=value - One or more -K options each specifying a valid user_attr(4)
  77   79   *              attribute.
  78   80   *
  79   81   */
  80   82  
  81   83  extern int **valid_lgroup(), isbusy();
  82   84  extern int valid_uid(), check_perm(), create_home(), move_dir();
  83   85  extern int valid_expire(), edit_group(), call_passmgmt();
  84   86  extern projid_t **valid_lproject();
  85   87  
  86   88  static uid_t uid;               /* new uid */
  87   89  static gid_t gid;                       /* gid of new login */
  88   90  static char *new_logname = NULL;        /* new login name with -l option */
  89   91  static char *uidstr = NULL;             /* uid from command line */
  90   92  static char *group = NULL;              /* group from command line */
  91   93  static char *grps = NULL;               /* multi groups from command line */
  92   94  static char *dir = NULL;                /* home dir from command line */
  93   95  static char *shell = NULL;              /* shell from command line */
  94   96  static char *comment = NULL;            /* comment from command line */
  95   97  static char *logname = NULL;            /* login name to add */
  96   98  static char *inactstr = NULL;           /* inactive from command line */
  97   99  static char *expire = NULL;             /* expiration date from command line */
  98  100  static char *projects = NULL;           /* project ids from command line */
  99  101  static char *usertype;
 100  102  
 101  103  char *cmdname;
 102  104  static char gidstring[32], uidstring[32];
 103  105  char inactstring[10];
 104  106  
 105  107  char *
 106  108  strcpmalloc(str)
 107  109  char *str;
 108  110  {
 109  111          if (str == NULL)
 110  112                  return (NULL);
 111  113  
 112  114          return (strdup(str));
 113  115  }
 114  116  struct passwd *
 115  117  passwd_cpmalloc(opw)
 116  118  struct passwd *opw;
 117  119  {
 118  120          struct passwd *npw;
 119  121  
 120  122          if (opw == NULL)
 121  123                  return (NULL);
 122  124  
 123  125  
 124  126          npw = malloc(sizeof (struct passwd));
 125  127  
 126  128          npw->pw_name = strcpmalloc(opw->pw_name);
 127  129          npw->pw_passwd = strcpmalloc(opw->pw_passwd);
 128  130          npw->pw_uid = opw->pw_uid;
 129  131          npw->pw_gid = opw->pw_gid;
 130  132          npw->pw_age = strcpmalloc(opw->pw_age);
 131  133          npw->pw_comment = strcpmalloc(opw->pw_comment);
 132  134          npw->pw_gecos  = strcpmalloc(opw->pw_gecos);
 133  135          npw->pw_dir = strcpmalloc(opw->pw_dir);
 134  136          npw->pw_shell = strcpmalloc(opw->pw_shell);
 135  137  
 136  138          return (npw);
 137  139  }
 138  140  
 139  141  int
 140  142  main(argc, argv)
 141  143  int argc;
 142  144  char **argv;
 143  145  {
 144  146          int ch, ret = EX_SUCCESS, call_pass = 0, oflag = 0;
 145  147          int tries, mflag = 0, inact, **gidlist, flag = 0;
 146  148          boolean_t fail_if_busy = B_FALSE;
 147  149          char *ptr;
 148  150          struct passwd *pstruct;         /* password struct for login */
 149  151          struct passwd *pw;
 150  152          struct group *g_ptr;    /* validated group from -g */
 151  153          struct stat statbuf;            /* status buffer for stat */
 152  154  #ifndef att
 153  155          FILE *pwf;              /* fille ptr for opened passwd file */
 154  156  #endif
 155  157          int warning;
 156  158          projid_t **projlist;
 157  159          char **nargv;                   /* arguments for execvp of passmgmt */
 158  160          int argindex;                   /* argument index into nargv */
 159  161          userattr_t *ua;
 160  162          char *val;
 161  163          int isrole;                     /* current account is role */
 162  164  
 163  165          cmdname = argv[0];
 164  166  
 165  167          if (geteuid() != 0) {
 166  168                  errmsg(M_PERM_DENIED);
 167  169                  exit(EX_NO_PERM);
 168  170          }
 169  171  
 170  172          opterr = 0;                     /* no print errors from getopt */
 171  173          /* get user type based on the program name */
 172  174          usertype = getusertype(argv[0]);
 173  175  
 174  176          while ((ch = getopt(argc, argv,
 175  177                                  "c:d:e:f:G:g:l:mop:s:u:A:P:R:K:")) != EOF)
 176  178                  switch (ch) {
 177  179                  case 'c':
 178  180                          comment = optarg;
 179  181                          flag++;
 180  182                          break;
 181  183                  case 'd':
 182  184                          dir = optarg;
 183  185                          fail_if_busy = B_TRUE;
 184  186                          flag++;
 185  187                          break;
 186  188                  case 'e':
 187  189                          expire = optarg;
 188  190                          flag++;
 189  191                          break;
 190  192                  case 'f':
 191  193                          inactstr = optarg;
 192  194                          flag++;
 193  195                          break;
 194  196                  case 'G':
 195  197                          grps = optarg;
 196  198                          flag++;
 197  199                          break;
 198  200                  case 'g':
 199  201                          group = optarg;
 200  202                          fail_if_busy = B_TRUE;
 201  203                          flag++;
 202  204                          break;
 203  205                  case 'l':
 204  206                          new_logname = optarg;
 205  207                          fail_if_busy = B_TRUE;
 206  208                          flag++;
 207  209                          break;
 208  210                  case 'm':
 209  211                          mflag++;
 210  212                          flag++;
 211  213                          fail_if_busy = B_TRUE;
 212  214                          break;
 213  215                  case 'o':
 214  216                          oflag++;
 215  217                          flag++;
 216  218                          fail_if_busy = B_TRUE;
 217  219                          break;
 218  220                  case 'p':
 219  221                          projects = optarg;
 220  222                          flag++;
 221  223                          break;
 222  224                  case 's':
 223  225                          shell = optarg;
 224  226                          flag++;
 225  227                          break;
 226  228                  case 'u':
 227  229                          uidstr = optarg;
 228  230                          flag++;
 229  231                          fail_if_busy = B_TRUE;
 230  232                          break;
 231  233                  case 'A':
 232  234                          change_key(USERATTR_AUTHS_KW, optarg);
 233  235                          flag++;
 234  236                          break;
 235  237                  case 'P':
 236  238                          change_key(USERATTR_PROFILES_KW, optarg);
 237  239                          flag++;
 238  240                          break;
 239  241                  case 'R':
 240  242                          change_key(USERATTR_ROLES_KW, optarg);
 241  243                          flag++;
 242  244                          break;
 243  245                  case 'K':
 244  246                          change_key(NULL, optarg);
 245  247                          flag++;
 246  248                          break;
 247  249                  default:
 248  250                  case '?':
 249  251                          if (is_role(usertype))
 250  252                                  errmsg(M_MRUSAGE);
 251  253                          else
 252  254                                  errmsg(M_MUSAGE);
 253  255                          exit(EX_SYNTAX);
 254  256                  }
 255  257  
 256  258          if (optind != argc - 1 || flag == 0) {
 257  259                  if (is_role(usertype))
 258  260                          errmsg(M_MRUSAGE);
 259  261                  else
 260  262                          errmsg(M_MUSAGE);
 261  263                  exit(EX_SYNTAX);
 262  264          }
 263  265  
 264  266          if ((!uidstr && oflag) || (mflag && !dir)) {
 265  267                  if (is_role(usertype))
 266  268                          errmsg(M_MRUSAGE);
 267  269                  else
 268  270                          errmsg(M_MUSAGE);
 269  271                  exit(EX_SYNTAX);
 270  272          }
 271  273  
 272  274          logname = argv[optind];
 273  275  
 274  276          /* Determine whether the account is a role or not */
 275  277          if ((ua = getusernam(logname)) == NULL ||
 276  278              (val = kva_match(ua->attr, USERATTR_TYPE_KW)) == NULL ||
 277  279              strcmp(val, USERATTR_TYPE_NONADMIN_KW) != 0)
 278  280                  isrole = 0;
 279  281          else
 280  282                  isrole = 1;
 281  283  
 282  284          /* Verify that rolemod is used for roles and usermod for users */
 283  285          if (isrole != is_role(usertype)) {
 284  286                  if (isrole)
 285  287                          errmsg(M_ISROLE);
 286  288                  else
 287  289                          errmsg(M_ISUSER);
 288  290                  exit(EX_SYNTAX);
 289  291          }
 290  292  
 291  293          /* Set the usertype key; defaults to the commandline  */
 292  294          usertype = getsetdefval(USERATTR_TYPE_KW, usertype);
 293  295  
 294  296          if (is_role(usertype)) {
 295  297                  /* Roles can't have roles */
 296  298                  if (getsetdefval(USERATTR_ROLES_KW, NULL) != NULL) {
 297  299                          errmsg(M_MRUSAGE);
 298  300                          exit(EX_SYNTAX);
 299  301                  }
 300  302                  /* If it was an ordinary user, delete its roles */
 301  303                  if (!isrole)
 302  304                          change_key(USERATTR_ROLES_KW, "");
 303  305          }
 304  306  
 305  307  #ifdef att
 306  308          pw = getpwnam(logname);
 307  309  #else
 308  310          /*
 309  311           * Do this with fgetpwent to make sure we are only looking on local
 310  312           * system (since passmgmt only works on local system).
 311  313           */
 312  314          if ((pwf = fopen("/etc/passwd", "r")) == NULL) {
 313  315                  errmsg(M_OOPS, "open", "/etc/passwd");
 314  316                  exit(EX_FAILURE);
 315  317          }
 316  318          while ((pw = fgetpwent(pwf)) != NULL)
 317  319                  if (strcmp(pw->pw_name, logname) == 0)
 318  320                          break;
 319  321  
 320  322          fclose(pwf);
 321  323  #endif
 322  324  
 323  325          if (pw == NULL) {
 324  326                  char            pwdb[NSS_BUFLEN_PASSWD];
 325  327                  struct passwd   pwd;
 326  328  
 327  329                  if (getpwnam_r(logname, &pwd, pwdb, sizeof (pwdb)) == NULL) {
 328  330                          /* This user does not exist. */
 329  331                          errmsg(M_EXIST, logname);
 330  332                          exit(EX_NAME_NOT_EXIST);
 331  333                  } else {
 332  334                          /* This user exists in non-local name service. */
 333  335                          errmsg(M_NONLOCAL, logname);
 334  336                          exit(EX_NOT_LOCAL);
 335  337                  }
 336  338          }
 337  339  
 338  340          pstruct = passwd_cpmalloc(pw);
 339  341  
 340  342          /*
 341  343           * We can't modify a logged in user if any of the following
 342  344           * are being changed:
 343  345           * uid (-u & -o), group (-g), home dir (-m), loginname (-l).
 344  346           * If none of those are specified it is okay to go ahead
 345  347           * some types of changes only take effect on next login, some
 346  348           * like authorisations and profiles take effect instantly.
 347  349           * One might think that -K type=role should require that the
 348  350           * user not be logged in, however this would make it very
 349  351           * difficult to make the root account a role using this command.
 350  352           */
 351  353          if (isbusy(logname)) {
 352  354                  if (fail_if_busy) {
 353  355                          errmsg(M_BUSY, logname, "change");
 354  356                          exit(EX_BUSY);
 355  357                  }
 356  358                  warningmsg(WARN_LOGGED_IN, logname);
 357  359          }
 358  360  
 359  361          if (new_logname && strcmp(new_logname, logname)) {
 360  362                  switch (valid_login(new_logname, (struct passwd **)NULL,
  
    | 
      ↓ open down ↓ | 
    329 lines elided | 
    
      ↑ open up ↑ | 
  
 361  363                          &warning)) {
 362  364                  case INVALID:
 363  365                          errmsg(M_INVALID, new_logname, "login name");
 364  366                          exit(EX_BADARG);
 365  367                          /*NOTREACHED*/
 366  368  
 367  369                  case NOTUNIQUE:
 368  370                          errmsg(M_USED, new_logname);
 369  371                          exit(EX_NAME_EXISTS);
 370  372                          /*NOTREACHED*/
      373 +
      374 +                case LONGNAME:
      375 +                        errmsg(M_TOO_LONG, new_logname);
      376 +                        exit(EX_BADARG);
      377 +                        /*NOTREACHED*/
      378 +
 371  379                  default:
 372  380                          call_pass = 1;
 373  381                          break;
 374  382                  }
 375  383                  if (warning)
 376  384                          warningmsg(warning, logname);
 377  385          }
 378  386  
 379  387          if (uidstr) {
 380  388                  /* convert uidstr to integer */
 381  389                  errno = 0;
 382  390                  uid = (uid_t)strtol(uidstr, &ptr, (int)10);
 383  391                  if (*ptr || errno == ERANGE) {
 384  392                          errmsg(M_INVALID, uidstr, "user id");
 385  393                          exit(EX_BADARG);
 386  394                  }
 387  395  
 388  396                  if (uid != pstruct->pw_uid) {
 389  397                          switch (valid_uid(uid, NULL)) {
 390  398                          case NOTUNIQUE:
 391  399                                  if (!oflag) {
 392  400                                          /* override not specified */
 393  401                                          errmsg(M_UID_USED, uid);
 394  402                                          exit(EX_ID_EXISTS);
 395  403                                  }
 396  404                                  break;
 397  405                          case RESERVED:
 398  406                                  errmsg(M_RESERVED, uid);
 399  407                                  break;
 400  408                          case TOOBIG:
 401  409                                  errmsg(M_TOOBIG, "uid", uid);
 402  410                                  exit(EX_BADARG);
 403  411                                  break;
 404  412                          }
 405  413  
 406  414                          call_pass = 1;
 407  415  
 408  416                  } else {
 409  417                          /* uid's the same, so don't change anything */
 410  418                          uidstr = NULL;
 411  419                          oflag = 0;
 412  420                  }
 413  421  
 414  422          } else uid = pstruct->pw_uid;
 415  423  
 416  424          if (group) {
 417  425                  switch (valid_group(group, &g_ptr, &warning)) {
 418  426                  case INVALID:
 419  427                          errmsg(M_INVALID, group, "group id");
 420  428                          exit(EX_BADARG);
 421  429                          /*NOTREACHED*/
 422  430                  case TOOBIG:
 423  431                          errmsg(M_TOOBIG, "gid", group);
 424  432                          exit(EX_BADARG);
 425  433                          /*NOTREACHED*/
 426  434                  case UNIQUE:
 427  435                          errmsg(M_GRP_NOTUSED, group);
 428  436                          exit(EX_NAME_NOT_EXIST);
 429  437                          /*NOTREACHED*/
 430  438                  case RESERVED:
 431  439                          gid = (gid_t)strtol(group, &ptr, (int)10);
 432  440                          errmsg(M_RESERVED_GID, gid);
 433  441                          break;
 434  442                  }
 435  443                  if (warning)
 436  444                          warningmsg(warning, group);
 437  445  
 438  446                  if (g_ptr != NULL)
 439  447                          gid = g_ptr->gr_gid;
 440  448                  else
 441  449                          gid = pstruct->pw_gid;
 442  450  
 443  451                  /* call passmgmt if gid is different, else ignore group */
 444  452                  if (gid != pstruct->pw_gid)
 445  453                          call_pass = 1;
 446  454                  else group = NULL;
 447  455  
 448  456          } else gid = pstruct->pw_gid;
 449  457  
 450  458          if (grps && *grps) {
 451  459                  if (!(gidlist = valid_lgroup(grps, gid)))
 452  460                          exit(EX_BADARG);
 453  461          } else
 454  462                  gidlist = (int **)0;
 455  463  
 456  464          if (projects && *projects) {
 457  465                  if (! (projlist = valid_lproject(projects)))
 458  466                          exit(EX_BADARG);
 459  467          } else
 460  468                  projlist = (projid_t **)0;
 461  469  
 462  470          if (dir) {
 463  471                  if (REL_PATH(dir)) {
 464  472                          errmsg(M_RELPATH, dir);
 465  473                          exit(EX_BADARG);
 466  474                  }
 467  475                  if (strcmp(pstruct->pw_dir, dir) == 0) {
 468  476                          /* home directory is the same so ignore dflag & mflag */
 469  477                          dir = NULL;
 470  478                          mflag = 0;
 471  479                  } else call_pass = 1;
 472  480          }
 473  481  
 474  482          if (mflag) {
 475  483                  if (stat(dir, &statbuf) == 0) {
 476  484                          /* Home directory exists */
 477  485                          if (check_perm(statbuf, pstruct->pw_uid,
 478  486                              pstruct->pw_gid, S_IWOTH|S_IXOTH) != 0) {
 479  487                                  errmsg(M_NO_PERM, logname, dir);
 480  488                                  exit(EX_NO_PERM);
 481  489                          }
 482  490  
 483  491                  } else ret = create_home(dir, NULL, uid, gid);
 484  492  
 485  493                  if (ret == EX_SUCCESS)
 486  494                          ret = move_dir(pstruct->pw_dir, dir, logname);
 487  495  
 488  496                  if (ret != EX_SUCCESS)
 489  497                          exit(ret);
 490  498          }
 491  499  
 492  500          if (shell) {
 493  501                  if (REL_PATH(shell)) {
 494  502                          errmsg(M_RELPATH, shell);
 495  503                          exit(EX_BADARG);
 496  504                  }
 497  505                  if (strcmp(pstruct->pw_shell, shell) == 0) {
 498  506                          /* ignore s option if shell is not different */
 499  507                          shell = NULL;
 500  508                  } else {
 501  509                          if (stat(shell, &statbuf) < 0 ||
 502  510                              (statbuf.st_mode & S_IFMT) != S_IFREG ||
 503  511                              (statbuf.st_mode & 0555) != 0555) {
 504  512  
 505  513                                  errmsg(M_INVALID, shell, "shell");
 506  514                                  exit(EX_BADARG);
 507  515                          }
 508  516  
 509  517                          call_pass = 1;
 510  518                  }
 511  519          }
 512  520  
 513  521          if (comment)
 514  522                  /* ignore comment if comment is not changed */
 515  523                  if (strcmp(pstruct->pw_comment, comment))
 516  524                          call_pass = 1;
 517  525                  else
 518  526                          comment = NULL;
 519  527  
 520  528          /* inactive string is a positive integer */
 521  529          if (inactstr) {
 522  530                  /* convert inactstr to integer */
 523  531                  inact = (int)strtol(inactstr, &ptr, 10);
 524  532                  if (*ptr || inact < 0) {
 525  533                          errmsg(M_INVALID, inactstr, "inactivity period");
 526  534                          exit(EX_BADARG);
 527  535                  }
 528  536                  call_pass = 1;
 529  537          }
 530  538  
 531  539          /* expiration string is a date, newer than today */
 532  540          if (expire) {
 533  541                  if (*expire &&
 534  542                      valid_expire(expire, (time_t *)0) == INVALID) {
 535  543                          errmsg(M_INVALID, expire, "expiration date");
 536  544                          exit(EX_BADARG);
 537  545                  }
 538  546                  call_pass = 1;
 539  547          }
 540  548  
 541  549          if (nkeys > 0)
 542  550                  call_pass = 1;
 543  551  
 544  552          /* that's it for validations - now do the work */
 545  553  
 546  554          if (grps) {
 547  555                  /* redefine login's supplentary group memberships */
 548  556                  ret = edit_group(logname, new_logname, gidlist, 1);
 549  557                  if (ret != EX_SUCCESS) {
 550  558                          errmsg(M_UPDATE, "modified");
 551  559                          exit(ret);
 552  560                  }
 553  561          }
 554  562          if (projects) {
 555  563                  ret = edit_project(logname, (char *)NULL, projlist, 0);
 556  564                  if (ret != EX_SUCCESS) {
 557  565                          errmsg(M_UPDATE, "modified");
 558  566                          exit(ret);
 559  567                  }
 560  568          }
 561  569  
 562  570  
 563  571          if (!call_pass) exit(ret);
 564  572  
 565  573          /* only get to here if need to call passmgmt */
 566  574          /* set up arguments to  passmgmt in nargv array */
 567  575          nargv = malloc((30 + nkeys * 2) * sizeof (char *));
 568  576  
 569  577          argindex = 0;
 570  578          nargv[argindex++] = PASSMGMT;
 571  579          nargv[argindex++] = "-m";       /* modify */
 572  580  
 573  581          if (comment) {  /* comment */
 574  582                  nargv[argindex++] = "-c";
 575  583                  nargv[argindex++] = comment;
 576  584          }
 577  585  
 578  586          if (dir) {
 579  587                  /* flags for home directory */
 580  588                  nargv[argindex++] = "-h";
 581  589                  nargv[argindex++] = dir;
 582  590          }
 583  591  
 584  592          if (group) {
 585  593                  /* set gid flag */
 586  594                  nargv[argindex++] = "-g";
 587  595                  (void) sprintf(gidstring, "%u", gid);
 588  596                  nargv[argindex++] = gidstring;
 589  597          }
 590  598  
 591  599          if (shell) {    /* shell */
 592  600                  nargv[argindex++] = "-s";
 593  601                  nargv[argindex++] = shell;
 594  602          }
 595  603  
 596  604          if (inactstr) {
 597  605                  nargv[argindex++] = "-f";
 598  606                  nargv[argindex++] = inactstr;
 599  607          }
 600  608  
 601  609          if (expire) {
 602  610                  nargv[argindex++] = "-e";
 603  611                  nargv[argindex++] = expire;
 604  612          }
 605  613  
 606  614          if (uidstr) {   /* set uid flag */
 607  615                  nargv[argindex++] = "-u";
 608  616                  (void) sprintf(uidstring, "%u", uid);
 609  617                  nargv[argindex++] = uidstring;
 610  618          }
 611  619  
 612  620          if (oflag) nargv[argindex++] = "-o";
 613  621  
 614  622          if (new_logname) {      /* redefine login name */
 615  623                  nargv[argindex++] = "-l";
 616  624                  nargv[argindex++] = new_logname;
 617  625          }
 618  626  
 619  627          if (nkeys > 0)
 620  628                  addkey_args(nargv, &argindex);
 621  629  
 622  630          /* finally - login name */
 623  631          nargv[argindex++] = logname;
 624  632  
 625  633          /* set the last to null */
 626  634          nargv[argindex++] = NULL;
 627  635  
 628  636          /* now call passmgmt */
 629  637          ret = PEX_FAILED;
 630  638          for (tries = 3; ret != PEX_SUCCESS && tries--; ) {
 631  639                  switch (ret = call_passmgmt(nargv)) {
 632  640                  case PEX_SUCCESS:
 633  641                  case PEX_BUSY:
 634  642                          break;
 635  643  
 636  644                  case PEX_HOSED_FILES:
 637  645                          errmsg(M_HOSED_FILES);
 638  646                          exit(EX_INCONSISTENT);
 639  647                          break;
 640  648  
 641  649                  case PEX_SYNTAX:
 642  650                  case PEX_BADARG:
 643  651                          /* should NEVER occur that passmgmt usage is wrong */
 644  652                          if (is_role(usertype))
 645  653                                  errmsg(M_MRUSAGE);
 646  654                          else
 647  655                                  errmsg(M_MUSAGE);
 648  656                          exit(EX_SYNTAX);
 649  657                          break;
 650  658  
 651  659                  case PEX_BADUID:
 652  660                          /* uid in use - shouldn't happen print message anyway */
 653  661                          errmsg(M_UID_USED, uid);
 654  662                          exit(EX_ID_EXISTS);
 655  663                          break;
 656  664  
 657  665                  case PEX_BADNAME:
 658  666                          /* invalid loname */
 659  667                          errmsg(M_USED, logname);
 660  668                          exit(EX_NAME_EXISTS);
 661  669                          break;
 662  670  
 663  671                  default:
 664  672                          errmsg(M_UPDATE, "modified");
 665  673                          exit(ret);
 666  674                          break;
 667  675                  }
 668  676          }
 669  677          if (tries == 0) {
 670  678                  errmsg(M_UPDATE, "modified");
 671  679          }
 672  680  
 673  681          exit(ret);
 674  682          /*NOTREACHED*/
 675  683  }
  
    | 
      ↓ open down ↓ | 
    295 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX