1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2013 RackTop Systems.
  24  * Copyright 2017 Gordon W. Ross
  25  */
  26 
  27 /*
  28  * OAM User Test program: get/set by UA key
  29  * See: $SRC/cmd/oamuser/user/useradd.c
  30  * and: $SRC/cmd/oamuser/user/funcs.c
  31  * (some code copied from funcs.c)
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <stdio.h>
  36 #include <string.h>
  37 #include <stdlib.h>
  38 #include <stddef.h>
  39 #include <getopt.h>
  40 #include <userdefs.h>
  41 #include <user_attr.h>
  42 
  43 void import_def(struct userdefs *ud);
  44 void update_def(struct userdefs *ud);
  45 void change_key(const char *, char *);
  46 
  47 extern const char *__progname;
  48 int vflag = 0;
  49 
  50 int
  51 main(int argc, char **argv)
  52 {
  53         struct userdefs *ud = NULL;
  54         int c;
  55 
  56         ud = _get_userdefs();
  57 
  58         while ((c = getopt(argc, argv, "vK:")) != EOF) {
  59                 switch (c) {
  60                 case 'K': /* Keyword=value */
  61                         change_key(NULL, optarg);
  62                         break;
  63                 case 'v': /* verbose */
  64                         vflag++;
  65                         break;
  66                 case '?':
  67                         (void) fprintf(stderr,
  68                             "usage: %s [-v] [-K key=value] [ -K ... ]\n",
  69                             __progname);
  70                         break;
  71                 }
  72         }
  73 
  74         /*
  75          * Override ud values we can't set by uakey, so they
  76          * don't depend on the test machine defaults file.
  77          */
  78         ud->defrid = 123;
  79         ud->defgroup = 456;
  80         ud->defgname = "TestGroup";
  81         ud->defparent = "TestDefParent";
  82         ud->defskel = "TestDefSkel";
  83         ud->defshell = "TestDefShell";
  84         ud->definact = 3;
  85         ud->defexpire = "TestDefExpire";
  86 
  87         ud->defproj = 7;
  88         ud->defprojname = "TestProject";
  89 
  90         import_def(ud);
  91 
  92         if (vflag) {
  93                 (void) printf("# Defaults:\n");
  94                 (void) fwrite_userdefs(stdout, ud);
  95                 (void) printf("\n");
  96         }
  97 
  98         update_def(ud);
  99 
 100         (void) fwrite_userdefs(stdout, ud);
 101 
 102         return (0);
 103 }
 104 
 105 /*
 106  * Some code copied from $SRC/cmd/oamuser/user/funcs.c
 107  * so we can simulate part of what that does without
 108  * dragging in all the parameter validation stuff.
 109  */
 110 
 111 typedef struct ua_key {
 112         const char      *key;
 113         char            *newvalue;
 114 } ua_key_t;
 115 
 116 static ua_key_t keys[] = {
 117         /* Only the keywords that appear in libuserdefs */
 118         { USERATTR_AUTHS_KW },
 119         { USERATTR_PROFILES_KW },
 120         { USERATTR_ROLES_KW },
 121         { USERATTR_LIMPRIV_KW },
 122         { USERATTR_DFLTPRIV_KW },
 123         { USERATTR_LOCK_AFTER_RETRIES_KW },
 124 };
 125 
 126 #define NKEYS   (sizeof (keys)/sizeof (ua_key_t))
 127 
 128 /* Import default keys for ordinary useradd */
 129 void
 130 import_def(struct userdefs *ud)
 131 {
 132         int i;
 133 
 134         /* Don't import the user type (skip i = 0) */
 135         for (i = 1; i < NKEYS; i++) {
 136                 if (keys[i].newvalue == NULL)
 137                         keys[i].newvalue =
 138                             userdef_get_by_uakey(ud, keys[i].key);
 139         }
 140 }
 141 
 142 /* Export command line keys to defaults for useradd -D */
 143 void
 144 update_def(struct userdefs *ud)
 145 {
 146         int i;
 147 
 148         for (i = 0; i < NKEYS; i++) {
 149                 if (keys[i].newvalue != NULL)
 150                         userdef_set_by_uakey(ud, keys[i].key,
 151                             keys[i].newvalue);
 152         }
 153 }
 154 
 155 /*
 156  * Change a key, there are three different call sequences:
 157  *
 158  *              key, value      - key with option letter, value.
 159  *              NULL, value     - -K key=value option.
 160  */
 161 
 162 void
 163 change_key(const char *key, char *value)
 164 {
 165         int i;
 166 
 167         if (key == NULL) {
 168                 key = value;
 169                 value = strchr(value, '=');
 170                 /* Bad value */
 171                 if (value == NULL) {
 172                         (void) fprintf(stderr, "Invalid value (missing)\n");
 173                         exit(EX_BADARG);
 174                 }
 175                 *value++ = '\0';
 176         }
 177 
 178         for (i = 0; i < NKEYS; i++) {
 179                 if (strcmp(key, keys[i].key) == 0) {
 180                         if (keys[i].newvalue != NULL) {
 181                                 /* Can't set a value twice */
 182                                 (void) fprintf(stderr,
 183                                     "Invalid value (duplicate)\n");
 184                                 exit(EX_BADARG);
 185                         }
 186 
 187                         keys[i].newvalue = value;
 188                         return;
 189                 }
 190         }
 191         (void) fprintf(stderr, "Invalid key: %s\n", key);
 192         exit(EX_BADARG);
 193 }