diff options
| -rw-r--r-- | include/usage.h | 10 | ||||
| -rw-r--r-- | loginutils/adduser.c | 104 |
2 files changed, 81 insertions, 33 deletions
diff --git a/include/usage.h b/include/usage.h index 9b5f484c1..d60a4dc78 100644 --- a/include/usage.h +++ b/include/usage.h | |||
| @@ -10,9 +10,13 @@ | |||
| 10 | #define adduser_full_usage \ | 10 | #define adduser_full_usage \ |
| 11 | "Adds a user to the system" \ | 11 | "Adds a user to the system" \ |
| 12 | "Options:\n" \ | 12 | "Options:\n" \ |
| 13 | "\t-h\t\thome directory\n" \ | 13 | "\t-h DIR\t\tAssign home directory DIR\n" \ |
| 14 | "\t-s\t\tshell\n" \ | 14 | "\t-g GECOS\t\tAssign gecos field GECOS\n" \ |
| 15 | "\t-g\t\tGECOS string\n" | 15 | "\t-s SHELL\t\tAssign login shell SHELL\n" \ |
| 16 | "\t-G\t\tAdd the user to existing group GROUP\n" \ | ||
| 17 | "\t-S\t\tcreate a system user (ignored)\n" \ | ||
| 18 | "\t-D\t\tDo not assign a password (logins still possible via ssh)\n" \ | ||
| 19 | "\t-H\t\tDo not create the home directory\n" | ||
| 16 | 20 | ||
| 17 | #define adjtimex_trivial_usage \ | 21 | #define adjtimex_trivial_usage \ |
| 18 | "[-q] [-o offset] [-f frequency] [-p timeconstant] [-t tick]" | 22 | "[-q] [-o offset] [-f frequency] [-p timeconstant] [-t tick]" |
diff --git a/loginutils/adduser.c b/loginutils/adduser.c index 6784d32cc..41dc9f019 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c | |||
| @@ -21,6 +21,9 @@ | |||
| 21 | * | 21 | * |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | #ifndef _GNU_SOURCE | ||
| 25 | #define _GNU_SOURCE | ||
| 26 | #endif | ||
| 24 | #include <errno.h> | 27 | #include <errno.h> |
| 25 | #include <fcntl.h> | 28 | #include <fcntl.h> |
| 26 | #include <stdarg.h> | 29 | #include <stdarg.h> |
| @@ -29,6 +32,7 @@ | |||
| 29 | #include <string.h> | 32 | #include <string.h> |
| 30 | #include <time.h> | 33 | #include <time.h> |
| 31 | #include <unistd.h> | 34 | #include <unistd.h> |
| 35 | #include <getopt.h> | ||
| 32 | #include <sys/param.h> | 36 | #include <sys/param.h> |
| 33 | #include <sys/stat.h> | 37 | #include <sys/stat.h> |
| 34 | #include <sys/types.h> | 38 | #include <sys/types.h> |
| @@ -89,21 +93,23 @@ static int passwd_study(const char *filename, struct passwd *p) | |||
| 89 | } | 93 | } |
| 90 | } | 94 | } |
| 91 | 95 | ||
| 92 | /* EDR check for an already existing gid */ | 96 | if (p->pw_gid == 0) { |
| 93 | while (getgrgid(p->pw_uid) != NULL) | 97 | /* EDR check for an already existing gid */ |
| 94 | p->pw_uid++; | 98 | while (getgrgid(p->pw_uid) != NULL) |
| 99 | p->pw_uid++; | ||
| 100 | |||
| 101 | /* EDR also check for an existing group definition */ | ||
| 102 | if (getgrnam(p->pw_name) != NULL) | ||
| 103 | return 3; | ||
| 95 | 104 | ||
| 96 | /* EDR also check for an existing group definition */ | 105 | /* EDR create new gid always = uid */ |
| 97 | if (getgrnam(p->pw_name) != NULL) | 106 | p->pw_gid = p->pw_uid; |
| 98 | return 3; | 107 | } |
| 99 | 108 | ||
| 100 | /* EDR bounds check */ | 109 | /* EDR bounds check */ |
| 101 | if ((p->pw_uid > max) || (p->pw_uid < min)) | 110 | if ((p->pw_uid > max) || (p->pw_uid < min)) |
| 102 | return 2; | 111 | return 2; |
| 103 | 112 | ||
| 104 | /* EDR create new gid always = uid */ | ||
| 105 | p->pw_gid = p->pw_uid; | ||
| 106 | |||
| 107 | /* return 1; */ | 113 | /* return 1; */ |
| 108 | return 0; | 114 | return 0; |
| 109 | } | 115 | } |
| @@ -127,7 +133,7 @@ static void passwd_wrapper(const char *login) | |||
| 127 | } | 133 | } |
| 128 | 134 | ||
| 129 | /* putpwent(3) remix */ | 135 | /* putpwent(3) remix */ |
| 130 | static int adduser(const char *filename, struct passwd *p) | 136 | static int adduser(const char *filename, struct passwd *p, int makehome, int setpass) |
| 131 | { | 137 | { |
| 132 | FILE *passwd; | 138 | FILE *passwd; |
| 133 | int r; | 139 | int r; |
| @@ -135,6 +141,11 @@ static int adduser(const char *filename, struct passwd *p) | |||
| 135 | FILE *shadow; | 141 | FILE *shadow; |
| 136 | struct spwd *sp; | 142 | struct spwd *sp; |
| 137 | #endif | 143 | #endif |
| 144 | int new_group = 1; | ||
| 145 | |||
| 146 | /* if using a pre-existing group, don't create one */ | ||
| 147 | if (p->pw_gid != 0) | ||
| 148 | new_group = 0; | ||
| 138 | 149 | ||
| 139 | /* make sure everything is kosher and setup uid && gid */ | 150 | /* make sure everything is kosher and setup uid && gid */ |
| 140 | passwd = bb_wfopen(filename, "a"); | 151 | passwd = bb_wfopen(filename, "a"); |
| @@ -181,29 +192,38 @@ static int adduser(const char *filename, struct passwd *p) | |||
| 181 | } | 192 | } |
| 182 | #endif | 193 | #endif |
| 183 | 194 | ||
| 184 | /* add to group */ | 195 | if (new_group) { |
| 185 | /* addgroup should be responsible for dealing w/ gshadow */ | 196 | /* add to group */ |
| 186 | addgroup_wrapper(p->pw_name, p->pw_gid); | 197 | /* addgroup should be responsible for dealing w/ gshadow */ |
| 198 | addgroup_wrapper(p->pw_name, p->pw_gid); | ||
| 199 | } | ||
| 187 | 200 | ||
| 188 | /* Clear the umask for this process so it doesn't | 201 | /* Clear the umask for this process so it doesn't |
| 189 | * * screw up the permissions on the mkdir and chown. */ | 202 | * * screw up the permissions on the mkdir and chown. */ |
| 190 | umask(0); | 203 | umask(0); |
| 191 | 204 | ||
| 192 | /* mkdir */ | 205 | if (makehome) { |
| 193 | if (mkdir(p->pw_dir, 0755)) { | 206 | /* mkdir */ |
| 194 | bb_perror_msg("%s", p->pw_dir); | 207 | if (mkdir(p->pw_dir, 0755)) { |
| 195 | } | 208 | bb_perror_msg("%s", p->pw_dir); |
| 196 | /* Set the owner and group so it is owned by the new user. */ | 209 | } |
| 197 | if (chown(p->pw_dir, p->pw_uid, p->pw_gid)) { | 210 | /* Set the owner and group so it is owned by the new user. */ |
| 198 | bb_perror_msg("%s", p->pw_dir); | 211 | if (chown(p->pw_dir, p->pw_uid, p->pw_gid)) { |
| 212 | bb_perror_msg("%s", p->pw_dir); | ||
| 213 | } | ||
| 214 | /* Now fix up the permissions to 2755. Can't do it before now | ||
| 215 | * since chown will clear the setgid bit */ | ||
| 216 | if (chmod(p->pw_dir, 02755)) { | ||
| 217 | bb_perror_msg("%s", p->pw_dir); | ||
| 218 | } | ||
| 199 | } | 219 | } |
| 200 | /* Now fix up the permissions to 2755. Can't do it before now | 220 | |
| 201 | * since chown will clear the setgid bit */ | 221 | if (setpass) { |
| 202 | if (chmod(p->pw_dir, 02755)) { | 222 | /* interactively set passwd */ |
| 203 | bb_perror_msg("%s", p->pw_dir); | 223 | passwd_wrapper(p->pw_name); |
| 204 | } | 224 | } |
| 205 | /* interactively set passwd */ | 225 | |
| 206 | passwd_wrapper(p->pw_name); | 226 | return 0; |
| 207 | } | 227 | } |
| 208 | 228 | ||
| 209 | 229 | ||
| @@ -219,6 +239,9 @@ void if_i_am_not_root(void) | |||
| 219 | } | 239 | } |
| 220 | } | 240 | } |
| 221 | 241 | ||
| 242 | #define SETPASS 1 | ||
| 243 | #define MAKEHOME 4 | ||
| 244 | |||
| 222 | /* | 245 | /* |
| 223 | * adduser will take a login_name as its first parameter. | 246 | * adduser will take a login_name as its first parameter. |
| 224 | * | 247 | * |
| @@ -230,19 +253,29 @@ void if_i_am_not_root(void) | |||
| 230 | * ________________________________________________________________________ */ | 253 | * ________________________________________________________________________ */ |
| 231 | int adduser_main(int argc, char **argv) | 254 | int adduser_main(int argc, char **argv) |
| 232 | { | 255 | { |
| 256 | struct passwd pw; | ||
| 233 | const char *login; | 257 | const char *login; |
| 234 | const char *gecos = default_gecos; | 258 | const char *gecos = default_gecos; |
| 235 | const char *home = NULL; | 259 | const char *home = NULL; |
| 236 | const char *shell = default_shell; | 260 | const char *shell = default_shell; |
| 237 | 261 | const char *usegroup = NULL; | |
| 238 | struct passwd pw; | 262 | int flags; |
| 263 | int setpass = 1; | ||
| 264 | int makehome = 1; | ||
| 239 | 265 | ||
| 240 | /* init */ | 266 | /* init */ |
| 241 | if (argc < 2) { | 267 | if (argc < 2) { |
| 242 | bb_show_usage(); | 268 | bb_show_usage(); |
| 243 | } | 269 | } |
| 244 | /* get args */ | 270 | /* get args */ |
| 245 | bb_getopt_ulflags(argc, argv, "h:g:s:", &home, &gecos, &shell); | 271 | flags = bb_getopt_ulflags(argc, argv, "h:g:s:G:DSH", &home, &gecos, &shell, &usegroup); |
| 272 | |||
| 273 | if (flags & SETPASS) { | ||
| 274 | setpass = 0; | ||
| 275 | } | ||
| 276 | if (flags & MAKEHOME) { | ||
| 277 | makehome = 0; | ||
| 278 | } | ||
| 246 | 279 | ||
| 247 | /* got root? */ | 280 | /* got root? */ |
| 248 | if_i_am_not_root(); | 281 | if_i_am_not_root(); |
| @@ -271,6 +304,17 @@ int adduser_main(int argc, char **argv) | |||
| 271 | pw.pw_dir = (char *)home; | 304 | pw.pw_dir = (char *)home; |
| 272 | pw.pw_shell = (char *)shell; | 305 | pw.pw_shell = (char *)shell; |
| 273 | 306 | ||
| 307 | if (usegroup) { | ||
| 308 | /* Add user to a group that already exists */ | ||
| 309 | struct group *g; | ||
| 310 | |||
| 311 | g = getgrnam(usegroup); | ||
| 312 | if (g == NULL) | ||
| 313 | bb_error_msg_and_die("group %s does not exist", usegroup); | ||
| 314 | |||
| 315 | pw.pw_gid = g->gr_gid; | ||
| 316 | } | ||
| 317 | |||
| 274 | /* grand finale */ | 318 | /* grand finale */ |
| 275 | return adduser(bb_path_passwd_file, &pw); | 319 | return adduser(bb_path_passwd_file, &pw, makehome, setpass); |
| 276 | } | 320 | } |
