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 }