]> granicus.if.org Git - shadow/blob - src/useradd.c
* src/useradd.c: Harmonize some error messages.
[shadow] / src / useradd.c
1 /*
2  * Copyright (c) 1991 - 1994, Julianne Frances Haugh
3  * Copyright (c) 1996 - 2000, Marek Michałkiewicz
4  * Copyright (c) 2000 - 2006, Tomasz Kłoczko
5  * Copyright (c) 2007 - 2008, Nicolas François
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the copyright holders or contributors may not be used to
17  *    endorse or promote products derived from this software without
18  *    specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include <config.h>
34
35 #ident "$Id$"
36
37 #include <assert.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <getopt.h>
42 #include <grp.h>
43 #include <lastlog.h>
44 #include <pwd.h>
45 #ifdef USE_PAM
46 #include "pam_defs.h"
47 #endif                          /* USE_PAM */
48 #include <stdio.h>
49 #include <sys/stat.h>
50 #include <sys/types.h>
51 #include <time.h>
52 #include "chkname.h"
53 #include "defines.h"
54 #include "faillog.h"
55 #include "getdef.h"
56 #include "groupio.h"
57 #include "nscd.h"
58 #include "prototypes.h"
59 #include "pwauth.h"
60 #include "pwio.h"
61 #ifdef  SHADOWGRP
62 #include "sgroupio.h"
63 #endif
64 #include "shadowio.h"
65
66 #ifndef SKEL_DIR
67 #define SKEL_DIR "/etc/skel"
68 #endif
69 #ifndef USER_DEFAULTS_FILE
70 #define USER_DEFAULTS_FILE "/etc/default/useradd"
71 #define NEW_USER_FILE "/etc/default/nuaddXXXXXX"
72 #endif
73 /*
74  * Needed for MkLinux DR1/2/2.1 - J.
75  */
76 #ifndef LASTLOG_FILE
77 #define LASTLOG_FILE "/var/log/lastlog"
78 #endif
79 /*
80  * Global variables
81  */
82 /*
83  * These defaults are used if there is no defaults file.
84  */
85 static gid_t def_group = 100;
86 static const char *def_gname = "other";
87 static const char *def_home = "/home";
88 static const char *def_shell = "";
89 static const char *def_template = SKEL_DIR;
90 static const char *def_create_mail_spool = "no";
91
92 static long def_inactive = -1;
93 static const char *def_expire = "";
94
95 static char def_file[] = USER_DEFAULTS_FILE;
96
97 #define VALID(s)        (strcspn (s, ":\n") == strlen (s))
98
99 static const char *user_name = "";
100 static const char *user_pass = "!";
101 static uid_t user_id;
102 static gid_t user_gid;
103 static const char *user_comment = "";
104 static const char *user_home = "";
105 static const char *user_shell = "";
106 static const char *create_mail_spool = "";
107
108 static long user_expire = -1;
109 static bool is_shadow_pwd;
110
111 #ifdef SHADOWGRP
112 static bool is_shadow_grp;
113 static bool sgr_locked = false;
114 #endif
115 static bool pw_locked = false;
116 static bool gr_locked = false;
117 static bool spw_locked = false;
118 static char **user_groups;      /* NULL-terminated list */
119 static long sys_ngroups;
120 static bool do_grp_update = false;      /* group files need to be updated */
121
122 static char *Prog;
123
124 static bool
125     bflg = false,               /* new default root of home directory */
126     cflg = false,               /* comment (GECOS) field for new account */
127     dflg = false,               /* home directory for new account */
128     Dflg = false,               /* set/show new user default values */
129     eflg = false,               /* days since 1970-01-01 when account is locked */
130     fflg = false,               /* days until account with expired password is locked */
131     gflg = false,               /* primary group ID for new account */
132     Gflg = false,               /* secondary group set for new account */
133     kflg = false,               /* specify a directory to fill new user directory */
134     lflg = false,               /* do not add user to lastlog database file */
135     mflg = false,               /* create user's home directory if it doesn't exist */
136     Nflg = false,               /* do not create a group having the same name as the user, but add the user to def_group (or the group specified with -g) */
137     oflg = false,               /* permit non-unique user ID to be specified with -u */
138     rflg = false,               /* create a system account */
139     sflg = false,               /* shell program for new account */
140     uflg = false,               /* specify user ID for new account */
141     Uflg = false;               /* create a group having the same name as the user */
142
143 static bool home_added = false;
144
145 /*
146  * exit status values
147  */
148 #define E_SUCCESS       0       /* success */
149 #define E_PW_UPDATE     1       /* can't update password file */
150 #define E_USAGE         2       /* invalid command syntax */
151 #define E_BAD_ARG       3       /* invalid argument to option */
152 #define E_UID_IN_USE    4       /* UID already in use (and no -o) */
153 #define E_NOTFOUND      6       /* specified group doesn't exist */
154 #define E_NAME_IN_USE   9       /* username already in use */
155 #define E_GRP_UPDATE    10      /* can't update group file */
156 #define E_HOMEDIR       12      /* can't create home directory */
157 #define E_MAIL_SPOOL    13      /* can't create mail spool */
158
159 #define DGROUP                  "GROUP="
160 #define HOME                    "HOME="
161 #define SHELL                   "SHELL="
162 #define INACT                   "INACTIVE="
163 #define EXPIRE                  "EXPIRE="
164 #define SKEL                    "SKEL="
165 #define CREATE_MAIL_SPOOL       "CREATE_MAIL_SPOOL="
166
167 /* local function prototypes */
168 static void fail_exit (int);
169 static struct group *getgr_nam_gid (const char *);
170 static long get_number (const char *);
171 static uid_t get_uid (const char *);
172 static void get_defaults (void);
173 static void show_defaults (void);
174 static int set_defaults (void);
175 static int get_groups (char *);
176 static void usage (void);
177 static void new_pwent (struct passwd *);
178
179 static long scale_age (long);
180 static void new_spent (struct spwd *);
181 static void grp_update (void);
182
183 static void process_flags (int argc, char **argv);
184 static void close_files (void);
185 static void open_files (void);
186 static void faillog_reset (uid_t);
187 static void lastlog_reset (uid_t);
188 static void usr_update (void);
189 static void create_home (void);
190 static void create_mail (void);
191
192 /*
193  * fail_exit - undo as much as possible
194  */
195 static void fail_exit (int code)
196 {
197         if (home_added) {
198                 rmdir (user_home);
199         }
200
201         if (spw_locked) {
202                 if (spw_unlock () == 0) {
203                         fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
204                         SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
205 #ifdef WITH_AUDIT
206                         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
207                                       "unlocking shadow file",
208                                       user_name, AUDIT_NO_ID, 0);
209 #endif
210                         /* continue */
211                 }
212         }
213         if (pw_locked) {
214                 if (pw_unlock () == 0) {
215                         fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ());
216                         SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
217 #ifdef WITH_AUDIT
218                         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
219                                       "unlocking passwd file",
220                                       user_name, AUDIT_NO_ID, 0);
221 #endif
222                         /* continue */
223                 }
224         }
225         if (gr_locked) {
226                 if (gr_unlock () == 0) {
227                         fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
228                         SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
229 #ifdef WITH_AUDIT
230                         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
231                                       "unlocking group file",
232                                       user_name, AUDIT_NO_ID, 0);
233 #endif
234                         /* continue */
235                 }
236         }
237 #ifdef  SHADOWGRP
238         if (sgr_locked) {
239                 if (sgr_unlock () == 0) {
240                         fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
241                         SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
242 #ifdef WITH_AUDIT
243                         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
244                                       "unlocking gshadow file",
245                                       user_name, AUDIT_NO_ID, 0);
246 #endif
247                         /* continue */
248                 }
249         }
250 #endif
251
252 #ifdef WITH_AUDIT
253         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
254                       "adding user",
255                       user_name, AUDIT_NO_ID, 0);
256 #endif
257         SYSLOG ((LOG_INFO, "failed adding user '%s', data deleted", user_name));
258         exit (code);
259 }
260
261 static struct group *getgr_nam_gid (const char *grname)
262 {
263         long gid;
264         char *errptr;
265
266         gid = strtol (grname, &errptr, 10);
267         if (*grname != '\0' && *errptr == '\0' && errno != ERANGE && gid >= 0) {
268                 return xgetgrgid ((gid_t) gid);
269         }
270         return xgetgrnam (grname);
271 }
272
273 static long get_number (const char *numstr)
274 {
275         long val;
276         char *errptr;
277
278         val = strtol (numstr, &errptr, 10);
279         if (('\0' != *errptr) || (ERANGE == errno)) {
280                 fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
281                          numstr);
282                 exit (E_BAD_ARG);
283         }
284         return val;
285 }
286
287 static uid_t get_uid (const char *uidstr)
288 {
289         long val;
290         char *errptr;
291
292         val = strtol (uidstr, &errptr, 10);
293         if (('\0' != *errptr) || (ERANGE == errno) || (val < 0)) {
294                 fprintf (stderr,
295                          _("%s: invalid numeric argument '%s'\n"), Prog,
296                          uidstr);
297                 exit (E_BAD_ARG);
298         }
299         return (uid_t) val;
300 }
301
302 #define MATCH(x,y) (strncmp((x),(y),strlen(y)) == 0)
303
304 /*
305  * get_defaults - read the defaults file
306  *
307  *      get_defaults() reads the defaults file for this command. It sets the
308  *      various values from the file, or uses built-in default values if the
309  *      file does not exist.
310  */
311 static void get_defaults (void)
312 {
313         FILE *fp;
314         char buf[1024];
315         char *cp, *ep;
316
317         /*
318          * Open the defaults file for reading.
319          */
320
321         fp = fopen (def_file, "r");
322         if (NULL == fp) {
323                 return;
324         }
325
326         /*
327          * Read the file a line at a time. Only the lines that have relevant
328          * values are used, everything else can be ignored.
329          */
330         while (fgets (buf, (int) sizeof buf, fp) == buf) {
331                 cp = strrchr (buf, '\n');
332                 if (NULL != cp) {
333                         *cp = '\0';
334                 }
335
336                 cp = strchr (buf, '=');
337                 if (NULL == cp) {
338                         continue;
339                 }
340
341                 cp++;
342
343                 /*
344                  * Primary GROUP identifier
345                  */
346                 if (MATCH (buf, DGROUP)) {
347                         unsigned int val = (unsigned int) strtoul (cp, &ep, 10);
348                         const struct group *grp;
349
350                         if (*cp != '\0' && *ep == '\0') { /* valid number */
351                                 def_group = val;
352                                 /* local, no need for xgetgrgid */
353                                 grp = getgrgid (def_group);
354                                 if (NULL != grp) {
355                                         def_gname = xstrdup (grp->gr_name);
356                                 } else {
357                                         fprintf (stderr,
358                                                  _("%s: GID '%s' does not exist\n"),
359                                                  Prog, cp);
360                                 }
361                         /* local, no need for xgetgrnam */
362                         } else if ((grp = getgrnam (cp)) != NULL) {
363                                 def_group = grp->gr_gid;
364                                 def_gname = xstrdup (cp);
365                         } else {
366                                 fprintf (stderr,
367                                          _("%s: group '%s' does not exist\n"), Prog, cp);
368                         }
369                 }
370
371                 /*
372                  * Default HOME filesystem
373                  */
374                 else if (MATCH (buf, HOME)) {
375                         def_home = xstrdup (cp);
376                 }
377
378                 /*
379                  * Default Login Shell command
380                  */
381                 else if (MATCH (buf, SHELL)) {
382                         def_shell = xstrdup (cp);
383                 }
384
385                 /*
386                  * Default Password Inactive value
387                  */
388                 else if (MATCH (buf, INACT)) {
389                         long val = strtol (cp, &ep, 10);
390
391                         if (('\0' != *cp) || (ERANGE == errno)) {
392                                 def_inactive = val;
393                         } else {
394                                 def_inactive = -1;
395                         }
396                 }
397
398                 /*
399                  * Default account expiration date
400                  */
401                 else if (MATCH (buf, EXPIRE)) {
402                         def_expire = xstrdup (cp);
403                 }
404
405                 /*
406                  * Default Skeleton information
407                  */
408                 else if (MATCH (buf, SKEL)) {
409                         if ('\0' == *cp) {
410                                 cp = SKEL_DIR;  /* XXX warning: const */
411                         }
412
413                         def_template = xstrdup (cp);
414                 }
415
416                 /*
417                  * Create by default user mail spool or not ?
418                  */
419                 else if (MATCH (buf, CREATE_MAIL_SPOOL)) {
420                         if (*cp == '\0') {
421                                 cp = CREATE_MAIL_SPOOL; /* XXX warning: const */
422                         }
423
424                         def_create_mail_spool = xstrdup (cp);
425                 }
426         }
427 }
428
429 /*
430  * show_defaults - show the contents of the defaults file
431  *
432  *      show_defaults() displays the values that are used from the default
433  *      file and the built-in values.
434  */
435 static void show_defaults (void)
436 {
437         printf ("GROUP=%u\n", (unsigned int) def_group);
438         printf ("HOME=%s\n", def_home);
439         printf ("INACTIVE=%ld\n", def_inactive);
440         printf ("EXPIRE=%s\n", def_expire);
441         printf ("SHELL=%s\n", def_shell);
442         printf ("SKEL=%s\n", def_template);
443         printf ("CREATE_MAIL_SPOOL=%s\n", def_create_mail_spool);
444 }
445
446 /*
447  * set_defaults - write new defaults file
448  *
449  *      set_defaults() re-writes the defaults file using the values that
450  *      are currently set. Duplicated lines are pruned, missing lines are
451  *      added, and unrecognized lines are copied as is.
452  */
453 static int set_defaults (void)
454 {
455         FILE *ifp;
456         FILE *ofp;
457         char buf[1024];
458         static char new_file[] = NEW_USER_FILE;
459         char *cp;
460         int ofd;
461         bool out_group = false;
462         bool out_home = false;
463         bool out_inactive = false;
464         bool out_expire = false;
465         bool out_shell = false;
466         bool out_skel = false;
467         bool out_create_mail_spool = false;
468
469         /*
470          * Create a temporary file to copy the new output to.
471          */
472         ofd = mkstemp (new_file);
473         if (-1 == ofd) {
474                 fprintf (stderr,
475                          _("%s: cannot create new defaults file\n"), Prog);
476                 return -1;
477         }
478
479         ofp = fdopen (ofd, "w");
480         if (NULL == ofp) {
481                 fprintf (stderr, _("%s: cannot open new defaults file\n"),
482                          Prog);
483                 return -1;
484         }
485
486         /*
487          * Open the existing defaults file and copy the lines to the
488          * temporary file, using any new values. Each line is checked
489          * to insure that it is not output more than once.
490          */
491         ifp = fopen (def_file, "r");
492         if (NULL == ifp) {
493                 fprintf (ofp, "# useradd defaults file\n");
494                 goto skip;
495         }
496
497         while (fgets (buf, (int) sizeof buf, ifp) == buf) {
498                 cp = strrchr (buf, '\n');
499                 if (NULL != cp) {
500                         *cp = '\0';
501                 }
502
503                 if (!out_group && MATCH (buf, DGROUP)) {
504                         fprintf (ofp, DGROUP "%u\n", (unsigned int) def_group);
505                         out_group = true;
506                 } else if (!out_home && MATCH (buf, HOME)) {
507                         fprintf (ofp, HOME "%s\n", def_home);
508                         out_home = true;
509                 } else if (!out_inactive && MATCH (buf, INACT)) {
510                         fprintf (ofp, INACT "%ld\n", def_inactive);
511                         out_inactive = true;
512                 } else if (!out_expire && MATCH (buf, EXPIRE)) {
513                         fprintf (ofp, EXPIRE "%s\n", def_expire);
514                         out_expire = true;
515                 } else if (!out_shell && MATCH (buf, SHELL)) {
516                         fprintf (ofp, SHELL "%s\n", def_shell);
517                         out_shell = true;
518                 } else if (!out_skel && MATCH (buf, SKEL)) {
519                         fprintf (ofp, SKEL "%s\n", def_template);
520                         out_skel = true;
521                 } else if (!out_create_mail_spool
522                            && MATCH (buf, CREATE_MAIL_SPOOL)) {
523                         fprintf (ofp, CREATE_MAIL_SPOOL "%s\n",
524                                  def_create_mail_spool);
525                         out_create_mail_spool = true;
526                 } else
527                         fprintf (ofp, "%s\n", buf);
528         }
529         (void) fclose (ifp);
530
531       skip:
532         /*
533          * Check each line to insure that every line was output. This
534          * causes new values to be added to a file which did not previously
535          * have an entry for that value.
536          */
537         if (!out_group)
538                 fprintf (ofp, DGROUP "%u\n", (unsigned int) def_group);
539         if (!out_home)
540                 fprintf (ofp, HOME "%s\n", def_home);
541         if (!out_inactive)
542                 fprintf (ofp, INACT "%ld\n", def_inactive);
543         if (!out_expire)
544                 fprintf (ofp, EXPIRE "%s\n", def_expire);
545         if (!out_shell)
546                 fprintf (ofp, SHELL "%s\n", def_shell);
547         if (!out_skel)
548                 fprintf (ofp, SKEL "%s\n", def_template);
549
550         if (!out_create_mail_spool)
551                 fprintf (ofp, CREATE_MAIL_SPOOL "%s\n", def_create_mail_spool);
552
553         /*
554          * Flush and close the file. Check for errors to make certain
555          * the new file is intact.
556          */
557         (void) fflush (ofp);
558         if ((ferror (ofp) != 0) || (fclose (ofp) != 0)) {
559                 unlink (new_file);
560                 return -1;
561         }
562
563         /*
564          * Rename the current default file to its backup name.
565          */
566         snprintf (buf, sizeof buf, "%s-", def_file);
567         if ((rename (def_file, buf) != 0) && (ENOENT != errno)) {
568                 snprintf (buf, sizeof buf, _("%s: rename: %s"), Prog, def_file);
569                 perror (buf);
570                 unlink (new_file);
571                 return -1;
572         }
573
574         /*
575          * Rename the new default file to its correct name.
576          */
577         if (rename (new_file, def_file) != 0) {
578                 snprintf (buf, sizeof buf, _("%s: rename: %s"), Prog, new_file);
579                 perror (buf);
580                 return -1;
581         }
582 #ifdef WITH_AUDIT
583         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
584                       "changing user defaults",
585                       NULL, AUDIT_NO_ID, 1);
586 #endif
587         SYSLOG ((LOG_INFO,
588                  "useradd defaults: GROUP=%u, HOME=%s, SHELL=%s, INACTIVE=%ld, "
589                  "EXPIRE=%s, SKEL=%s, CREATE_MAIL_SPOOL=%s",
590                  (unsigned int) def_group, def_home, def_shell,
591                  def_inactive, def_expire, def_template,
592                  def_create_mail_spool));
593         return 0;
594 }
595
596 /*
597  * get_groups - convert a list of group names to an array of group IDs
598  *
599  *      get_groups() takes a comma-separated list of group names and
600  *      converts it to a NULL-terminated array. Any unknown group
601  *      names are reported as errors.
602  */
603 static int get_groups (char *list)
604 {
605         char *cp;
606         const struct group *grp;
607         int errors = 0;
608         int ngroups = 0;
609
610         if ('\0' == *list) {
611                 return 0;
612         }
613
614         /*
615          * So long as there is some data to be converted, strip off
616          * each name and look it up. A mix of numerical and string
617          * values for group identifiers is permitted.
618          */
619         do {
620                 /*
621                  * Strip off a single name from the list
622                  */
623                 cp = strchr (list, ',');
624                 if (NULL != cp) {
625                         *cp++ = '\0';
626                 }
627
628                 /*
629                  * Names starting with digits are treated as numerical
630                  * GID values, otherwise the string is looked up as is.
631                  */
632                 grp = getgr_nam_gid (list);
633
634                 /*
635                  * There must be a match, either by GID value or by
636                  * string name.
637                  */
638                 if (NULL == grp) {
639                         fprintf (stderr, _("%s: group '%s' does not exist\n"),
640                                  Prog, list);
641                         errors++;
642                 }
643                 list = cp;
644
645                 /*
646                  * If the group doesn't exist, don't dump core...
647                  * Instead, try the next one.  --marekm
648                  */
649                 if (NULL == grp) {
650                         continue;
651                 }
652
653 #ifdef  USE_NIS
654                 /*
655                  * Don't add this group if they are an NIS group. Tell
656                  * the user to go to the server for this group.
657                  */
658                 if (__isgrNIS ()) {
659                         fprintf (stderr,
660                                  _("%s: group '%s' is a NIS group.\n"),
661                                  Prog, grp->gr_name);
662                         continue;
663                 }
664 #endif
665
666                 if (ngroups == sys_ngroups) {
667                         fprintf (stderr,
668                                  _
669                                  ("%s: too many groups specified (max %d).\n"),
670                                  Prog, ngroups);
671                         break;
672                 }
673
674                 /*
675                  * Add the group name to the user's list of groups.
676                  */
677                 user_groups[ngroups++] = xstrdup (grp->gr_name);
678         } while (NULL != list);
679
680         user_groups[ngroups] = (char *) 0;
681
682         /*
683          * Any errors in finding group names are fatal
684          */
685         if (0 != errors) {
686                 return -1;
687         }
688
689         return 0;
690 }
691
692 /*
693  * usage - display usage message and exit
694  */
695 static void usage (void)
696 {
697         fputs (_("Usage: useradd [options] LOGIN\n"
698                  "\n"
699                  "Options:\n"
700                  "  -b, --base-dir BASE_DIR       base directory for the new user account\n"
701                  "                                home directory\n"
702                  "  -c, --comment COMMENT         set the GECOS field for the new user account\n"
703                  "  -d, --home-dir HOME_DIR       home directory for the new user account\n"
704                  "  -D, --defaults                print or save modified default useradd\n"
705                  "                                configuration\n"
706                  "  -e, --expiredate EXPIRE_DATE  set account expiration date to EXPIRE_DATE\n"
707                  "  -f, --inactive INACTIVE       set password inactive after expiration\n"
708                  "                                to INACTIVE\n"
709                  "  -g, --gid GROUP               force use GROUP for the new user account\n"
710                  "  -G, --groups GROUPS           list of supplementary groups for the new\n"
711                  "                                user account\n"
712                  "  -h, --help                    display this help message and exit\n"
713                  "  -k, --skel SKEL_DIR           specify an alternative skel directory\n"
714                  "  -K, --key KEY=VALUE           overrides /etc/login.defs defaults\n"
715                  "  -l,                           do not add the user to the lastlog and\n"
716                  "                                faillog databases\n"
717                  "  -m, --create-home             create home directory for the new user\n"
718                  "                                account\n"
719                  "  -N, --no-user-group           do not create a group with the same name as\n"
720                  "                                the user\n"
721                  "  -o, --non-unique              allow create user with duplicate\n"
722                  "                                (non-unique) UID\n"
723                  "  -p, --password PASSWORD       use encrypted password for the new user\n"
724                  "                                account\n"
725                  "  -r, --system                  create a system account\n"
726                  "  -s, --shell SHELL             the login shell for the new user account\n"
727                  "  -u, --uid UID                 force use the UID for the new user account\n"
728                  "  -U, --user-group              create a group with the same name as the user\n"
729                  "\n"), stderr);
730         exit (E_USAGE);
731 }
732
733 /*
734  * new_pwent - initialize the values in a password file entry
735  *
736  *      new_pwent() takes all of the values that have been entered and
737  *      fills in a (struct passwd) with them.
738  */
739 static void new_pwent (struct passwd *pwent)
740 {
741         memzero (pwent, sizeof *pwent);
742         pwent->pw_name = (char *) user_name;
743         if (is_shadow_pwd) {
744                 pwent->pw_passwd = (char *) SHADOW_PASSWD_STRING;
745         } else {
746                 pwent->pw_passwd = (char *) user_pass;
747         }
748
749         pwent->pw_uid = user_id;
750         pwent->pw_gid = user_gid;
751         pwent->pw_gecos = (char *) user_comment;
752         pwent->pw_dir = (char *) user_home;
753         pwent->pw_shell = (char *) user_shell;
754 }
755
756 static long scale_age (long x)
757 {
758         if (x <= 0) {
759                 return x;
760         }
761
762         return x * (DAY / SCALE);
763 }
764
765 /*
766  * new_spent - initialize the values in a shadow password file entry
767  *
768  *      new_spent() takes all of the values that have been entered and
769  *      fills in a (struct spwd) with them.
770  */
771 static void new_spent (struct spwd *spent)
772 {
773         memzero (spent, sizeof *spent);
774         spent->sp_namp = (char *) user_name;
775         spent->sp_pwdp = (char *) user_pass;
776         spent->sp_lstchg = (long) time ((time_t *) 0) / SCALE;
777         if (!rflg) {
778                 spent->sp_min = scale_age (getdef_num ("PASS_MIN_DAYS", -1));
779                 spent->sp_max = scale_age (getdef_num ("PASS_MAX_DAYS", -1));
780                 spent->sp_warn = scale_age (getdef_num ("PASS_WARN_AGE", -1));
781                 spent->sp_inact = scale_age (def_inactive);
782                 spent->sp_expire = scale_age (user_expire);
783         } else {
784                 spent->sp_min = scale_age (-1);
785                 spent->sp_max = scale_age (-1);
786                 spent->sp_warn = scale_age (-1);
787                 spent->sp_inact = scale_age (-1);
788                 spent->sp_expire = scale_age (-1);
789         }
790         spent->sp_flag = SHADOW_SP_FLAG_UNSET;
791 }
792
793 /*
794  * grp_update - add user to secondary group set
795  *
796  *      grp_update() takes the secondary group set given in user_groups
797  *      and adds the user to each group given by that set.
798  *
799  *      The group files are opened and locked in open_files().
800  *
801  *      close_files() should be called afterwards to commit the changes
802  *      and unlocking the group files.
803  */
804 static void grp_update (void)
805 {
806         const struct group *grp;
807         struct group *ngrp;
808
809 #ifdef  SHADOWGRP
810         const struct sgrp *sgrp;
811         struct sgrp *nsgrp;
812 #endif
813
814         /*
815          * Scan through the entire group file looking for the groups that
816          * the user is a member of.
817          */
818         for (gr_rewind (), grp = gr_next (); NULL != grp; grp = gr_next ()) {
819
820                 /*
821                  * See if the user specified this group as one of their
822                  * concurrent groups.
823                  */
824                 if (!is_on_list (user_groups, grp->gr_name)) {
825                         continue;
826                 }
827
828                 /*
829                  * Make a copy - gr_update() will free() everything
830                  * from the old entry, and we need it later.
831                  */
832                 ngrp = __gr_dup (grp);
833                 if (NULL == ngrp) {
834                         fprintf (stderr,
835                                  _("%s: Out of memory. Cannot update %s.\n"),
836                                  Prog, gr_dbname ());
837                         fail_exit (E_GRP_UPDATE);       /* XXX */
838                 }
839
840                 /* 
841                  * Add the username to the list of group members and
842                  * update the group entry to reflect the change.
843                  */
844                 ngrp->gr_mem = add_list (ngrp->gr_mem, user_name);
845                 if (gr_update (ngrp) == 0) {
846                         fprintf (stderr,
847                                  _("%s: failed to prepare the new %s entry '%s'\n"),
848                                  Prog, gr_dbname (), ngrp->gr_name);
849                         fail_exit (E_GRP_UPDATE);
850                 }
851 #ifdef WITH_AUDIT
852                 audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
853                               "adding user to group",
854                               user_name, AUDIT_NO_ID, 1);
855 #endif
856                 SYSLOG ((LOG_INFO, "add '%s' to group '%s'",
857                          user_name, ngrp->gr_name));
858         }
859
860 #ifdef  SHADOWGRP
861         if (!is_shadow_grp)
862                 return;
863
864         /*
865          * Scan through the entire shadow group file looking for the groups
866          * that the user is a member of. The administrative list isn't
867          * modified.
868          */
869         for (sgr_rewind (), sgrp = sgr_next (); NULL != sgrp; sgrp = sgr_next ()) {
870
871                 /*
872                  * See if the user specified this group as one of their
873                  * concurrent groups.
874                  */
875                 if (gr_locate (sgrp->sg_name) == NULL) {
876                         continue;
877                 }
878
879                 if (!is_on_list (user_groups, sgrp->sg_name)) {
880                         continue;
881                 }
882
883                 /*
884                  * Make a copy - sgr_update() will free() everything
885                  * from the old entry, and we need it later.
886                  */
887                 nsgrp = __sgr_dup (sgrp);
888                 if (NULL == nsgrp) {
889                         fprintf (stderr,
890                                  _("%s: Out of memory. Cannot update %s.\n"),
891                                  Prog, sgr_dbname ());
892                         fail_exit (E_GRP_UPDATE);       /* XXX */
893                 }
894
895                 /* 
896                  * Add the username to the list of group members and
897                  * update the group entry to reflect the change.
898                  */
899                 nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_name);
900                 if (sgr_update (nsgrp) == 0) {
901                         fprintf (stderr,
902                                  _("%s: failed to prepare the new %s entry '%s'\n"),
903                                  Prog, sgr_dbname (), nsgrp->sg_name);
904                         fail_exit (E_GRP_UPDATE);
905                 }
906 #ifdef WITH_AUDIT
907                 audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
908                               "adding user to shadow group",
909                               user_name, AUDIT_NO_ID, 1);
910 #endif
911                 SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'",
912                          user_name, nsgrp->sg_name));
913         }
914 #endif                          /* SHADOWGRP */
915 }
916
917 /*
918  * process_flags - perform command line argument setting
919  *
920  *      process_flags() interprets the command line arguments and sets
921  *      the values that the user will be created with accordingly. The
922  *      values are checked for sanity.
923  */
924 static void process_flags (int argc, char **argv)
925 {
926         const struct group *grp;
927         bool anyflag = false;
928         char *cp;
929
930         {
931                 /*
932                  * Parse the command line options.
933                  */
934                 int c;
935                 static struct option long_options[] = {
936                         {"base-dir", required_argument, NULL, 'b'},
937                         {"comment", required_argument, NULL, 'c'},
938                         {"home-dir", required_argument, NULL, 'd'},
939                         {"defaults", no_argument, NULL, 'D'},
940                         {"expiredate", required_argument, NULL, 'e'},
941                         {"inactive", required_argument, NULL, 'f'},
942                         {"gid", required_argument, NULL, 'g'},
943                         {"groups", required_argument, NULL, 'G'},
944                         {"help", no_argument, NULL, 'h'},
945                         {"skel", required_argument, NULL, 'k'},
946                         {"key", required_argument, NULL, 'K'},
947                         {"create-home", no_argument, NULL, 'm'},
948                         {"no-user-group", no_argument, NULL, 'N'},
949                         {"non-unique", no_argument, NULL, 'o'},
950                         {"password", required_argument, NULL, 'p'},
951                         {"system", no_argument, NULL, 'r'},
952                         {"shell", required_argument, NULL, 's'},
953                         {"uid", required_argument, NULL, 'u'},
954                         {"user-group", no_argument, NULL, 'U'},
955                         {NULL, 0, NULL, '\0'}
956                 };
957                 while ((c =
958                         getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:lmMNop:rs:u:U",
959                                      long_options, NULL)) != -1) {
960                         switch (c) {
961                         case 'b':
962                                 if (   ( !VALID (optarg) )
963                                     || ( optarg[0] != '/' )) {
964                                         fprintf (stderr,
965                                                  _("%s: invalid base directory '%s'\n"),
966                                                  Prog, optarg);
967                                         exit (E_BAD_ARG);
968                                 }
969                                 def_home = optarg;
970                                 bflg = true;
971                                 break;
972                         case 'c':
973                                 if (!VALID (optarg)) {
974                                         fprintf (stderr,
975                                                  _("%s: invalid comment '%s'\n"),
976                                                  Prog, optarg);
977                                         exit (E_BAD_ARG);
978                                 }
979                                 user_comment = optarg;
980                                 cflg = true;
981                                 break;
982                         case 'd':
983                                 if (   ( !VALID (optarg) )
984                                     || ( optarg[0] != '/' )) {
985                                         fprintf (stderr,
986                                                  _("%s: invalid home directory '%s'\n"),
987                                                  Prog, optarg);
988                                         exit (E_BAD_ARG);
989                                 }
990                                 user_home = optarg;
991                                 dflg = true;
992                                 break;
993                         case 'D':
994                                 if (anyflag) {
995                                         usage ();
996                                 }
997                                 Dflg = true;
998                                 break;
999                         case 'e':
1000                                 if ('\0' != *optarg) {
1001                                         user_expire = strtoday (optarg);
1002                                         if (user_expire == -1) {
1003                                                 fprintf (stderr,
1004                                                          _("%s: invalid date '%s'\n"),
1005                                                          Prog, optarg);
1006                                                 exit (E_BAD_ARG);
1007                                         }
1008                                 } else {
1009                                         user_expire = -1;
1010                                 }
1011
1012                                 /*
1013                                  * -e "" is allowed - it's a no-op without /etc/shadow
1014                                  */
1015                                 if (('\0' != *optarg) && !is_shadow_pwd) {
1016                                         fprintf (stderr,
1017                                                  _("%s: shadow passwords required for -e\n"),
1018                                                  Prog);
1019                                         exit (E_USAGE);
1020                                 }
1021                                 if (Dflg) {
1022                                         def_expire = optarg;
1023                                 }
1024                                 eflg = true;
1025                                 break;
1026                         case 'f':
1027                                 def_inactive = get_number (optarg);
1028                                 /*
1029                                  * -f -1 is allowed - it's a no-op without /etc/shadow
1030                                  */
1031                                 if ((-1 != def_inactive) && !is_shadow_pwd) {
1032                                         fprintf (stderr,
1033                                                  _
1034                                                  ("%s: shadow passwords required for -f\n"),
1035                                                  Prog);
1036                                         exit (E_USAGE);
1037                                 }
1038                                 fflg = true;
1039                                 break;
1040                         case 'g':
1041                                 grp = getgr_nam_gid (optarg);
1042                                 if (NULL == grp) {
1043                                         fprintf (stderr,
1044                                                  _("%s: group '%s' does not exist\n"),
1045                                                  Prog, optarg);
1046                                         exit (E_NOTFOUND);
1047                                 }
1048                                 if (Dflg) {
1049                                         def_group = grp->gr_gid;
1050                                         def_gname = optarg;
1051                                 } else {
1052                                         user_gid = grp->gr_gid;
1053                                 }
1054                                 gflg = true;
1055                                 break;
1056                         case 'G':
1057                                 if (get_groups (optarg) != 0) {
1058                                         exit (E_NOTFOUND);
1059                                 }
1060                                 if (NULL != user_groups[0]) {
1061                                         do_grp_update = true;
1062                                 }
1063                                 Gflg = true;
1064                                 break;
1065                         case 'h':
1066                                 usage ();
1067                                 break;
1068                         case 'k':
1069                                 def_template = optarg;
1070                                 kflg = true;
1071                                 break;
1072                         case 'K':
1073                                 /*
1074                                  * override login.defs defaults (-K name=value)
1075                                  * example: -K UID_MIN=100 -K UID_MAX=499
1076                                  * note: -K UID_MIN=10,UID_MAX=499 doesn't work yet
1077                                  */
1078                                 cp = strchr (optarg, '=');
1079                                 if (NULL == cp) {
1080                                         fprintf (stderr,
1081                                                  _("%s: -K requires KEY=VALUE\n"),
1082                                                  Prog);
1083                                         exit (E_BAD_ARG);
1084                                 }
1085                                 /* terminate name, point to value */
1086                                 *cp = '\0';
1087                                 cp++;
1088                                 if (putdef_str (optarg, cp) < 0) {
1089                                         exit (E_BAD_ARG);
1090                                 }
1091                                 break;
1092                         case 'l':
1093                                 lflg = true;
1094                                 break;
1095                         case 'm':
1096                                 mflg = true;
1097                                 break;
1098                         case 'N':
1099                                 Nflg = true;
1100                                 break;
1101                         case 'o':
1102                                 oflg = true;
1103                                 break;
1104                         case 'p':       /* set encrypted password */
1105                                 if (!VALID (optarg)) {
1106                                         fprintf (stderr,
1107                                                  _("%s: invalid field '%s'\n"),
1108                                                  Prog, optarg);
1109                                         exit (E_BAD_ARG);
1110                                 }
1111                                 user_pass = optarg;
1112                                 break;
1113                         case 'r':
1114                                 rflg = true;
1115                                 break;
1116                         case 's':
1117                                 if (   ( !VALID (optarg) )
1118                                     || (   ('\0' != optarg[0])
1119                                         && ('/'  != optarg[0])
1120                                         && ('*'  != optarg[0]) )) {
1121                                         fprintf (stderr,
1122                                                  _("%s: invalid shell '%s'\n"),
1123                                                  Prog, optarg);
1124                                         exit (E_BAD_ARG);
1125                                 }
1126                                 user_shell = optarg;
1127                                 def_shell = optarg;
1128                                 sflg = true;
1129                                 break;
1130                         case 'u':
1131                                 user_id = get_uid (optarg);
1132                                 uflg = true;
1133                                 break;
1134                         case 'U':
1135                                 Uflg = true;
1136                                 break;
1137                         default:
1138                                 usage ();
1139                         }
1140                         anyflag = true;
1141                 }
1142         }
1143
1144         if (!gflg && !Nflg && !Uflg) {
1145                 /* Get the settings from login.defs */
1146                 Uflg = getdef_bool ("USERGROUPS_ENAB");
1147         }
1148
1149         /*
1150          * Certain options are only valid in combination with others.
1151          * Check it here so that they can be specified in any order.
1152          */
1153         if (oflg && !uflg) {
1154                 fprintf (stderr,
1155                          _("%s: %s flag is only allowed with the %s flag\n"),
1156                          Prog, "-o", "-u");
1157                 usage ();
1158         }
1159         if (kflg && !mflg) {
1160                 fprintf (stderr,
1161                          _("%s: %s flag is only allowed with the %s flag\n"),
1162                          Prog, "-k", "-m");
1163                 usage ();
1164         }
1165         if (Uflg && gflg) {
1166                 fprintf (stderr,
1167                          _("%s: options %s and %s conflict\n"),
1168                          Prog, "-U", "-g");
1169                 usage ();
1170         }
1171         if (Uflg && Nflg) {
1172                 fprintf (stderr,
1173                          _("%s: options %s and %s conflict\n"),
1174                          Prog, "-U", "-N");
1175                 usage ();
1176         }
1177
1178         /*
1179          * Either -D or username is required. Defaults can be set with -D
1180          * for the -b, -e, -f, -g, -s options only.
1181          */
1182         if (Dflg) {
1183                 if (optind != argc) {
1184                         usage ();
1185                 }
1186
1187                 if (uflg || oflg || Gflg || dflg || cflg || mflg) {
1188                         usage ();
1189                 }
1190         } else {
1191                 if (optind != argc - 1) {
1192                         usage ();
1193                 }
1194
1195                 user_name = argv[optind];
1196                 if (!is_valid_user_name (user_name)) {
1197                         fprintf (stderr,
1198                                  _("%s: invalid user name '%s'\n"),
1199                                  Prog, user_name);
1200 #ifdef WITH_AUDIT
1201                         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1202                                       "adding user",
1203                                       user_name, AUDIT_NO_ID, 0);
1204 #endif
1205                         exit (E_BAD_ARG);
1206                 }
1207                 if (!dflg) {
1208                         char *uh;
1209
1210                         uh = xmalloc (strlen (def_home) +
1211                                       strlen (user_name) + 2);
1212                         sprintf (uh, "%s/%s", def_home, user_name);
1213                         user_home = uh;
1214                 }
1215         }
1216
1217         if (!eflg) {
1218                 user_expire = strtoday (def_expire);
1219         }
1220
1221         if (!gflg) {
1222                 user_gid = def_group;
1223         }
1224
1225         if (!sflg) {
1226                 user_shell = def_shell;
1227         }
1228
1229         /* TODO: add handle change default spool mail creation by 
1230            -K CREATE_MAIL_SPOOL={yes,no}. It need rewrite internal API for handle
1231            shadow tools configuration */
1232         create_mail_spool = def_create_mail_spool;
1233 }
1234
1235 /*
1236  * close_files - close all of the files that were opened
1237  *
1238  *      close_files() closes all of the files that were opened for this
1239  *      new user. This causes any modified entries to be written out.
1240  */
1241 static void close_files (void)
1242 {
1243         if (pw_close () == 0) {
1244                 fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ());
1245                 SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ()));
1246                 fail_exit (E_PW_UPDATE);
1247         }
1248         if (is_shadow_pwd && (spw_close () == 0)) {
1249                 fprintf (stderr,
1250                          _("%s: failure while writing changes to %s\n"), Prog, spw_dbname ());
1251                 SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ()));
1252                 fail_exit (E_PW_UPDATE);
1253         }
1254         if (do_grp_update) {
1255                 if (gr_close () == 0) {
1256                         fprintf (stderr,
1257                                  _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ());
1258                         SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ()));
1259                         fail_exit (E_GRP_UPDATE);
1260                 }
1261 #ifdef  SHADOWGRP
1262                 if (is_shadow_grp && (sgr_close () == 0)) {
1263                         fprintf (stderr,
1264                                  _("%s: failure while writing changes to %s\n"),
1265                                  Prog, sgr_dbname ());
1266                         SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ()));
1267                         fail_exit (E_GRP_UPDATE);
1268                 }
1269 #endif
1270         }
1271         if (is_shadow_pwd) {
1272                 if (spw_unlock () == 0) {
1273                         fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
1274                         SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
1275 #ifdef WITH_AUDIT
1276                         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1277                                       "unlocking shadow file",
1278                                       user_name, AUDIT_NO_ID, 0);
1279 #endif
1280                         /* continue */
1281                 }
1282                 spw_locked = false;
1283         }
1284         if (pw_unlock () == 0) {
1285                 fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ());
1286                 SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
1287 #ifdef WITH_AUDIT
1288                 audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1289                               "unlocking passwd file",
1290                               user_name, AUDIT_NO_ID, 0);
1291 #endif
1292                 /* continue */
1293         }
1294         pw_locked = false;
1295         if (gr_unlock () == 0) {
1296                 fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
1297                 SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
1298 #ifdef WITH_AUDIT
1299                 audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1300                               "unlocking group file",
1301                               user_name, AUDIT_NO_ID, 0);
1302 #endif
1303                 /* continue */
1304         }
1305         gr_locked = false;
1306 #ifdef  SHADOWGRP
1307         if (is_shadow_grp) {
1308                 if (sgr_unlock () == 0) {
1309                         fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
1310                         SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
1311 #ifdef WITH_AUDIT
1312                         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1313                                       "unlocking gshadow file",
1314                                       user_name, AUDIT_NO_ID, 0);
1315 #endif
1316                         /* continue */
1317                 }
1318                 sgr_locked = false;
1319         }
1320 #endif
1321 }
1322
1323 /*
1324  * open_files - lock and open the password files
1325  *
1326  *      open_files() opens the two password files.
1327  */
1328 static void open_files (void)
1329 {
1330         if (pw_lock () == 0) {
1331                 fprintf (stderr,
1332                          _("%s: cannot lock %s; try again later.\n"),
1333                          Prog, pw_dbname ());
1334                 exit (E_PW_UPDATE);
1335         }
1336         pw_locked = true;
1337         if (pw_open (O_RDWR) == 0) {
1338                 fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ());
1339                 fail_exit (E_PW_UPDATE);
1340         }
1341         if (is_shadow_pwd) {
1342                 if (spw_lock () == 0) {
1343                         fprintf (stderr,
1344                                  _("%s: cannot lock %s; try again later.\n"),
1345                                  Prog, spw_dbname ());
1346                         fail_exit (E_PW_UPDATE);
1347                 }
1348                 spw_locked = true;
1349                 if (spw_open (O_RDWR) == 0) {
1350                         fprintf (stderr,
1351                                  _("%s: cannot open %s\n"),
1352                                  Prog, spw_dbname ());
1353                         fail_exit (E_PW_UPDATE);
1354                 }
1355         }
1356
1357         /*
1358          * Lock and open the group file.
1359          */
1360         if (gr_lock () == 0) {
1361                 fprintf (stderr,
1362                          _("%s: cannot lock %s; try again later.\n"),
1363                          Prog, gr_dbname ());
1364                 fail_exit (E_GRP_UPDATE);
1365         }
1366         gr_locked = true;
1367         if (gr_open (O_RDWR) == 0) {
1368                 fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
1369                 fail_exit (E_GRP_UPDATE);
1370         }
1371 #ifdef  SHADOWGRP
1372         if (is_shadow_grp) {
1373                 if (sgr_lock () == 0) {
1374                         fprintf (stderr,
1375                                  _("%s: cannot lock %s; try again later.\n"),
1376                                  Prog, sgr_dbname ());
1377                         fail_exit (E_GRP_UPDATE);
1378                 }
1379                 sgr_locked = true;
1380                 if (sgr_open (O_RDWR) == 0) {
1381                         fprintf (stderr,
1382                                  _("%s: cannot open %s\n"),
1383                                  Prog, sgr_dbname ());
1384                         fail_exit (E_GRP_UPDATE);
1385                 }
1386         }
1387 #endif
1388 }
1389
1390 static char *empty_list = NULL;
1391
1392 /*
1393  * new_grent - initialize the values in a group file entry
1394  *
1395  *      new_grent() takes all of the values that have been entered and fills
1396  *      in a (struct group) with them.
1397  */
1398
1399 static void new_grent (struct group *grent)
1400 {
1401         memzero (grent, sizeof *grent);
1402         grent->gr_name = (char *) user_name;
1403         grent->gr_passwd = SHADOW_PASSWD_STRING;        /* XXX warning: const */
1404         grent->gr_gid = user_gid;
1405         grent->gr_mem = &empty_list;
1406 }
1407
1408 #ifdef  SHADOWGRP
1409 /*
1410  * new_sgent - initialize the values in a shadow group file entry
1411  *
1412  *      new_sgent() takes all of the values that have been entered and fills
1413  *      in a (struct sgrp) with them.
1414  */
1415
1416 static void new_sgent (struct sgrp *sgent)
1417 {
1418         memzero (sgent, sizeof *sgent);
1419         sgent->sg_name = (char *) user_name;
1420         sgent->sg_passwd = "!"; /* XXX warning: const */
1421         sgent->sg_adm = &empty_list;
1422         sgent->sg_mem = &empty_list;
1423 }
1424 #endif                          /* SHADOWGRP */
1425
1426
1427 /*
1428  * grp_add - add new group file entries
1429  *
1430  *      grp_add() writes the new records to the group files.
1431  */
1432
1433 static void grp_add (void)
1434 {
1435         struct group grp;
1436
1437 #ifdef  SHADOWGRP
1438         struct sgrp sgrp;
1439 #endif                          /* SHADOWGRP */
1440
1441         /*
1442          * Create the initial entries for this new group.
1443          */
1444         new_grent (&grp);
1445 #ifdef  SHADOWGRP
1446         new_sgent (&sgrp);
1447 #endif                          /* SHADOWGRP */
1448
1449         /*
1450          * Write out the new group file entry.
1451          */
1452         if (gr_update (&grp) == 0) {
1453                 fprintf (stderr,
1454                          _("%s: failed to prepare the new %s entry '%s'\n"),
1455                          Prog, gr_dbname (), grp.gr_name);
1456                 fail_exit (E_GRP_UPDATE);
1457         }
1458 #ifdef  SHADOWGRP
1459         /*
1460          * Write out the new shadow group entries as well.
1461          */
1462         if (is_shadow_grp && (sgr_update (&sgrp) == 0)) {
1463                 fprintf (stderr,
1464                          _("%s: failed to prepare the new %s entry '%s'\n"),
1465                          Prog, sgr_dbname (), sgrp.sg_name);
1466                 fail_exit (E_GRP_UPDATE);
1467         }
1468 #endif                          /* SHADOWGRP */
1469         SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid));
1470         do_grp_update = true;
1471 }
1472
1473 static void faillog_reset (uid_t uid)
1474 {
1475         struct faillog fl;
1476         int fd;
1477         off_t offset_uid = (off_t) (sizeof fl) * uid;
1478
1479         if (access (FAILLOG_FILE, F_OK) != 0) {
1480                 return;
1481         }
1482
1483         memzero (&fl, sizeof (fl));
1484
1485         fd = open (FAILLOG_FILE, O_RDWR);
1486         if (   (-1 == fd)
1487             || (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
1488             || (write (fd, &fl, sizeof (fl)) != (ssize_t) sizeof (fl))
1489             || (close (fd) != 0)) {
1490                 fprintf (stderr,
1491                          _("%s: failed to reset the faillog entry of UID %lu: %s\n"),
1492                          Prog, (unsigned long) uid, strerror (errno));
1493                 SYSLOG ((LOG_WARN, "failed to reset the faillog entry of UID %lu", (unsigned long) uid));
1494                 /* continue */
1495         }
1496 }
1497
1498 static void lastlog_reset (uid_t uid)
1499 {
1500         struct lastlog ll;
1501         int fd;
1502         off_t offset_uid = (off_t) (sizeof ll) * uid;
1503
1504         if (access (LASTLOG_FILE, F_OK) != 0) {
1505                 return;
1506         }
1507
1508         memzero (&ll, sizeof (ll));
1509
1510         fd = open (LASTLOG_FILE, O_RDWR);
1511         if (   (-1 == fd)
1512             || (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
1513             || (write (fd, &ll, sizeof (ll)) != (ssize_t) sizeof (ll))
1514             || (close (fd) != 0)) {
1515                 fprintf (stderr,
1516                          _("%s: failed to reset the lastlog entry of UID %lu: %s\n"),
1517                          Prog, (unsigned long) uid, strerror (errno));
1518                 SYSLOG ((LOG_WARN, "failed to reset the lastlog entry of UID %lu", (unsigned long) uid));
1519                 /* continue */
1520         }
1521 }
1522
1523 /*
1524  * usr_update - create the user entries
1525  *
1526  *      usr_update() creates the password file entries for this user
1527  *      and will update the group entries if required.
1528  */
1529 static void usr_update (void)
1530 {
1531         struct passwd pwent;
1532         struct spwd spent;
1533
1534         /*
1535          * Fill in the password structure with any new fields, making
1536          * copies of strings.
1537          */
1538         new_pwent (&pwent);
1539         new_spent (&spent);
1540
1541         /*
1542          * Create a syslog entry. We need to do this now in case anything
1543          * happens so we know what we were trying to accomplish.
1544          */
1545         SYSLOG ((LOG_INFO,
1546                  "new user: name=%s, UID=%u, GID=%u, home=%s, shell=%s",
1547                  user_name, (unsigned int) user_id,
1548                  (unsigned int) user_gid, user_home, user_shell));
1549
1550         /*
1551          * Initialize faillog and lastlog entries for this UID in case
1552          * it belongs to a previously deleted user. We do it only if
1553          * no user with this UID exists yet (entries for shared UIDs
1554          * are left unchanged).  --marekm
1555          */
1556         /* local, no need for xgetpwuid */
1557         if ((!lflg) && (getpwuid (user_id) == NULL)) {
1558                 faillog_reset (user_id);
1559                 lastlog_reset (user_id);
1560         }
1561
1562         /*
1563          * Put the new (struct passwd) in the table.
1564          */
1565         if (pw_update (&pwent) == 0) {
1566                 fprintf (stderr,
1567                          _("%s: failed to prepare the new %s entry '%s'\n"),
1568                          Prog, pw_dbname (), pwent.pw_name);
1569                 fail_exit (E_PW_UPDATE);
1570         }
1571
1572         /*
1573          * Put the new (struct spwd) in the table.
1574          */
1575         if (is_shadow_pwd && (spw_update (&spent) == 0)) {
1576                 fprintf (stderr,
1577                          _("%s: failed to prepare the new %s entry '%s'\n"),
1578                          Prog, spw_dbname (), spent.sp_namp);
1579 #ifdef WITH_AUDIT
1580                 audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1581                               "adding shadow password",
1582                               user_name, (unsigned int) user_id, 0);
1583 #endif
1584                 fail_exit (E_PW_UPDATE);
1585         }
1586 #ifdef WITH_AUDIT
1587         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1588                       "adding user",
1589                       user_name, (unsigned int) user_id, 1);
1590 #endif
1591
1592         /*
1593          * Do any group file updates for this user.
1594          */
1595         if (do_grp_update) {
1596                 grp_update ();
1597         }
1598 }
1599
1600 /*
1601  * create_home - create the user's home directory
1602  *
1603  *      create_home() creates the user's home directory if it does not
1604  *      already exist. It will be created mode 755 owned by the user
1605  *      with the user's default group.
1606  */
1607 static void create_home (void)
1608 {
1609         if (access (user_home, F_OK) != 0) {
1610                 /* XXX - create missing parent directories.  --marekm */
1611                 if (mkdir (user_home, 0) != 0) {
1612                         fprintf (stderr,
1613                                  _
1614                                  ("%s: cannot create directory %s\n"),
1615                                  Prog, user_home);
1616 #ifdef WITH_AUDIT
1617                         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1618                                       "adding home directory",
1619                                       user_name, (unsigned int) user_id, 0);
1620 #endif
1621                         fail_exit (E_HOMEDIR);
1622                 }
1623                 chown (user_home, user_id, user_gid);
1624                 chmod (user_home,
1625                        0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK));
1626                 home_added = true;
1627 #ifdef WITH_AUDIT
1628                 audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1629                               "adding home directory",
1630                               user_name, (unsigned int) user_id, 1);
1631 #endif
1632         }
1633 }
1634
1635 /*
1636  * create_mail - create the user's mail spool
1637  *
1638  *      create_mail() creates the user's mail spool if it does not already
1639  *      exist. It will be created mode 660 owned by the user and group
1640  *      'mail'
1641  */
1642 static void create_mail (void)
1643 {
1644         char *spool, *file;
1645         int fd;
1646         struct group *gr;
1647         gid_t gid;
1648         mode_t mode;
1649
1650         if (strcasecmp (create_mail_spool, "yes") == 0) {
1651                 spool = getdef_str ("MAIL_DIR");
1652                 if (NULL == spool) {
1653                         spool = "/var/mail";
1654                 }
1655                 file = alloca (strlen (spool) + strlen (user_name) + 2);
1656                 sprintf (file, "%s/%s", spool, user_name);
1657                 fd = open (file, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0);
1658                 if (fd < 0) {
1659                         perror (_("Creating mailbox file"));
1660                         return;
1661                 }
1662
1663                 gr = getgrnam ("mail"); /* local, no need for xgetgrnam */
1664                 if (NULL == gr) {
1665                         fputs (_("Group 'mail' not found. Creating the user mailbox file with 0600 mode.\n"),
1666                                stderr);
1667                         gid = user_gid;
1668                         mode = 0600;
1669                 } else {
1670                         gid = gr->gr_gid;
1671                         mode = 0660;
1672                 }
1673
1674                 if (   (fchown (fd, user_id, gid) != 0)
1675                     || (fchmod (fd, mode) != 0)) {
1676                         perror (_("Setting mailbox file permissions"));
1677                 }
1678
1679                 close (fd);
1680         }
1681 }
1682
1683 /*
1684  * main - useradd command
1685  */
1686 int main (int argc, char **argv)
1687 {
1688 #ifdef USE_PAM
1689         pam_handle_t *pamh = NULL;
1690         int retval;
1691 #endif
1692
1693 #ifdef WITH_AUDIT
1694         audit_help_open ();
1695 #endif
1696
1697         /*
1698          * Get my name so that I can use it to report errors.
1699          */
1700         Prog = Basename (argv[0]);
1701
1702         (void) setlocale (LC_ALL, "");
1703         (void) bindtextdomain (PACKAGE, LOCALEDIR);
1704         (void) textdomain (PACKAGE);
1705
1706         OPENLOG ("useradd");
1707
1708         sys_ngroups = sysconf (_SC_NGROUPS_MAX);
1709         user_groups = malloc ((1 + sys_ngroups) * sizeof (char *));
1710         /*
1711          * Initialize the list to be empty
1712          */
1713         user_groups[0] = (char *) 0;
1714
1715
1716         is_shadow_pwd = spw_file_present ();
1717 #ifdef SHADOWGRP
1718         is_shadow_grp = sgr_file_present ();
1719 #endif
1720
1721         get_defaults ();
1722
1723         process_flags (argc, argv);
1724
1725 #ifdef USE_PAM
1726         retval = PAM_SUCCESS;
1727
1728         {
1729                 struct passwd *pampw;
1730                 pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
1731                 if (pampw == NULL) {
1732                         retval = PAM_USER_UNKNOWN;
1733                 }
1734
1735                 if (PAM_SUCCESS == retval) {
1736                         retval = pam_start ("useradd", pampw->pw_name,
1737                                             &conv, &pamh);
1738                 }
1739         }
1740
1741         if (PAM_SUCCESS == retval) {
1742                 retval = pam_authenticate (pamh, 0);
1743         }
1744
1745         if (PAM_SUCCESS == retval) {
1746                 retval = pam_acct_mgmt (pamh, 0);
1747         }
1748
1749         if (PAM_SUCCESS != retval) {
1750                 (void) pam_end (pamh, retval);
1751                 fprintf (stderr, _("%s: PAM authentication failed\n"), Prog);
1752                 fail_exit (1);
1753         }
1754 #endif                          /* USE_PAM */
1755
1756         /*
1757          * See if we are messing with the defaults file, or creating
1758          * a new user.
1759          */
1760         if (Dflg) {
1761                 if (gflg || bflg || fflg || eflg || sflg) {
1762                         exit ((set_defaults () != 0) ? 1 : 0);
1763                 }
1764
1765                 show_defaults ();
1766                 exit (E_SUCCESS);
1767         }
1768
1769         /*
1770          * Start with a quick check to see if the user exists.
1771          */
1772         if (getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */
1773                 fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name);
1774 #ifdef WITH_AUDIT
1775                 audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1776                               "adding user",
1777                               user_name, AUDIT_NO_ID, 0);
1778 #endif
1779                 fail_exit (E_NAME_IN_USE);
1780         }
1781
1782         /*
1783          * Don't blindly overwrite a group when a user is added...
1784          * If you already have a group username, and want to add the user
1785          * to that group, use useradd -g username username.
1786          * --bero
1787          */
1788         if (Uflg) {
1789                 /* local, no need for xgetgrnam */
1790                 if (getgrnam (user_name) != NULL) {
1791                         fprintf (stderr,
1792                                  _("%s: group %s exists - if you want to add this user to that group, use -g.\n"),
1793                                  Prog, user_name);
1794 #ifdef WITH_AUDIT
1795                         audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1796                                       "adding group",
1797                                       user_name, AUDIT_NO_ID, 0);
1798 #endif
1799                         fail_exit (E_NAME_IN_USE);
1800                 }
1801         }
1802
1803         /*
1804          * Do the hard stuff:
1805          * - open the files,
1806          * - create the user entries,
1807          * - create the home directory,
1808          * - create user mail spool,
1809          * - flush nscd caches for passwd and group services,
1810          * - then close and update the files.
1811          */
1812         open_files ();
1813
1814         if (!oflg) {
1815                 /* first, seek for a valid uid to use for this user.
1816                  * We do this because later we can use the uid we found as
1817                  * gid too ... --gafton */
1818                 if (!uflg) {
1819                         if (find_new_uid (rflg, &user_id, NULL) < 0) {
1820                                 fprintf (stderr, _("%s: can't create user\n"), Prog);
1821                                 fail_exit (E_UID_IN_USE);
1822                         }
1823                 } else {
1824                         if (getpwuid (user_id) != NULL) {
1825                                 fprintf (stderr,
1826                                          _("%s: UID %lu is not unique\n"),
1827                                          Prog, (unsigned long) user_id);
1828 #ifdef WITH_AUDIT
1829                                 audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
1830                                               "adding user",
1831                                               user_name, (unsigned int) user_id, 0);
1832 #endif
1833                                 fail_exit (E_UID_IN_USE);
1834                         }
1835                 }
1836         }
1837
1838         /* do we have to add a group for that user? This is why we need to
1839          * open the group files in the open_files() function  --gafton */
1840         if (Uflg) {
1841                 if (find_new_gid (rflg, &user_gid, &user_id) < 0) {
1842                         fprintf (stderr,
1843                                  _("%s: can't create group\n"),
1844                                  Prog);
1845                         fail_exit (4);
1846                 }
1847                 grp_add ();
1848         }
1849
1850         usr_update ();
1851
1852         if (mflg) {
1853                 create_home ();
1854                 if (home_added)
1855                         copy_tree (def_template, user_home, user_id, user_gid);
1856                 else
1857                         fprintf (stderr,
1858                                  _
1859                                  ("%s: warning: the home directory already exists.\n"
1860                                   "Not copying any file from skel directory into it.\n"),
1861                                  Prog);
1862
1863         } else if (getdef_str ("CREATE_HOME") != NULL) {
1864                 /*
1865                  * RedHat added the CREATE_HOME option in login.defs in their
1866                  * version of shadow-utils (which makes -m the default, with
1867                  * new -M option to turn it off). Unfortunately, this
1868                  * changes the way useradd works (it can be run by scripts
1869                  * expecting some standard behaviour), compared to other
1870                  * Unices and other Linux distributions, and also adds a lot
1871                  * of confusion :-(.
1872                  * So we now recognize CREATE_HOME and give a warning here
1873                  * (better than "configuration error ... notify administrator"
1874                  * errors in every program that reads /etc/login.defs). -MM
1875                  */
1876                 fprintf (stderr,
1877                          _
1878                          ("%s: warning: CREATE_HOME not supported, please use -m instead.\n"),
1879                          Prog);
1880         }
1881
1882         create_mail ();
1883
1884         close_files ();
1885
1886         nscd_flush_cache ("passwd");
1887         nscd_flush_cache ("group");
1888
1889 #ifdef USE_PAM
1890         (void) pam_end (pamh, PAM_SUCCESS);
1891 #endif                          /* USE_PAM */
1892
1893         return E_SUCCESS;
1894 }
1895