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