Commit fadacc97 fadacc97a46f7911e1c25e9fd20b081faed85570 by Sergey Poznyakoff

(create_home_dir,home_dir_mode): New variables

(options): New option --create-home-dir
(imap4d_check_home_dir): New function
1 parent c42f9ecf
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2001, 2002, 2003, 2004, 2 Copyright (C) 1999, 2001, 2002, 2003, 2004,
3 2005 Free Software Foundation, Inc. 3 2005, 2006 Free Software Foundation, Inc.
4 4
5 GNU Mailutils is free software; you can redistribute it and/or modify 5 GNU Mailutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
...@@ -39,6 +39,9 @@ struct daemon_param daemon_param = { ...@@ -39,6 +39,9 @@ struct daemon_param daemon_param = {
39 39
40 int login_disabled; /* Disable LOGIN command */ 40 int login_disabled; /* Disable LOGIN command */
41 int tls_required; /* Require STARTTLS */ 41 int tls_required; /* Require STARTTLS */
42 int create_home_dir; /* Create home directory if it does not
43 exist */
44 int home_dir_mode;
42 45
43 /* Number of child processes. */ 46 /* Number of child processes. */
44 size_t children; 47 size_t children;
...@@ -46,8 +49,9 @@ size_t children; ...@@ -46,8 +49,9 @@ size_t children;
46 const char *program_version = "imap4d (" PACKAGE_STRING ")"; 49 const char *program_version = "imap4d (" PACKAGE_STRING ")";
47 static char doc[] = N_("GNU imap4d -- the IMAP4D daemon"); 50 static char doc[] = N_("GNU imap4d -- the IMAP4D daemon");
48 51
49 #define ARG_LOGIN_DISABLED 1 52 #define ARG_LOGIN_DISABLED 1
50 #define ARG_TLS_REQUIRED 2 53 #define ARG_TLS_REQUIRED 2
54 #define ARG_CREATE_HOME_DIR 3
51 55
52 static struct argp_option options[] = { 56 static struct argp_option options[] = {
53 {"other-namespace", 'O', N_("PATHLIST"), 0, 57 {"other-namespace", 'O', N_("PATHLIST"), 0,
...@@ -56,6 +60,8 @@ static struct argp_option options[] = { ...@@ -56,6 +60,8 @@ static struct argp_option options[] = {
56 N_("Set the `shared' namespace"), 0}, 60 N_("Set the `shared' namespace"), 0},
57 {"login-disabled", ARG_LOGIN_DISABLED, NULL, 0, 61 {"login-disabled", ARG_LOGIN_DISABLED, NULL, 0,
58 N_("Disable LOGIN command")}, 62 N_("Disable LOGIN command")},
63 {"create-home-dir", ARG_CREATE_HOME_DIR, N_("MODE"), OPTION_ARG_OPTIONAL,
64 N_("Create home directory, if it does not exist")},
59 #ifdef WITH_TLS 65 #ifdef WITH_TLS
60 {"tls-required", ARG_TLS_REQUIRED, NULL, 0, 66 {"tls-required", ARG_TLS_REQUIRED, NULL, 0,
61 N_("Always require STARTTLS before entering authentication phase")}, 67 N_("Always require STARTTLS before entering authentication phase")},
...@@ -117,6 +123,19 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) ...@@ -117,6 +123,19 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state)
117 imap4d_capability_add (IMAP_CAPA_LOGINDISABLED); 123 imap4d_capability_add (IMAP_CAPA_LOGINDISABLED);
118 break; 124 break;
119 125
126 case ARG_CREATE_HOME_DIR:
127 create_home_dir = 1;
128 if (arg)
129 {
130 char *p;
131 home_dir_mode = strtoul (arg, &p, 8);
132 if (p || (home_dir_mode & 0777))
133 argp_error (state, _("Invalid mode specification: %s"), arg);
134 }
135 else
136 home_dir_mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
137 break;
138
120 #ifdef WITH_TLS 139 #ifdef WITH_TLS
121 case ARG_TLS_REQUIRED: 140 case ARG_TLS_REQUIRED:
122 tls_required = 1; 141 tls_required = 1;
...@@ -397,3 +416,34 @@ imap4d_daemon (unsigned int maxchildren, unsigned int port) ...@@ -397,3 +416,34 @@ imap4d_daemon (unsigned int maxchildren, unsigned int port)
397 close (connfd); 416 close (connfd);
398 } 417 }
399 } 418 }
419
420 int
421 imap4d_check_home_dir (const char *dir, uid_t uid, gid_t gid)
422 {
423 struct stat st;
424
425 if (stat (homedir, &st))
426 {
427 if (errno == ENOENT && create_home_dir)
428 {
429 mode_t mode = umask (0);
430 int rc = mkdir (homedir, home_dir_mode);
431 umask (mode);
432 if (rc)
433 {
434 mu_error ("Cannot create home directory `%s': %s",
435 homedir, mu_strerror (errno));
436 return 1;
437 }
438 if (chown (homedir, uid, gid))
439 {
440 mu_error ("Cannot set owner for home directory `%s': %s",
441 homedir, mu_strerror (errno));
442 return 1;
443 }
444 }
445 }
446
447 return 0;
448 }
449
......