Commit 35baeb22 35baeb22c0864d1f73c31a36742c0af7a7ad7e22 by Sergey Poznyakoff

Allow to set file permissions of the local mailboxes during creation.

* include/mailutils/stream.h (MU_STREAM_IRGRP, MU_STREAM_IWGRP)
(MU_STREAM_IROTH, MU_STREAM_IWOTH, MU_STREAM_IMASK): New defines.
* include/mailutils/mutil.h (mu_stream_flags_to_mode): New
prototype.
* libproto/maildir/mbox.c (maildir_create, maildir_flush)
(maildir_scan0): Consider mailbox flags	to determine its file
mode.
* mailbox/amd.c (amd_open, amd_message_stream_open): Likewise.
* mailbox/file_stream.c (_file_open): Likewise.
* mailbox/mutil.c (mu_stream_flags_to_mode): New file.

* imap4d/namespace.c (namespace_getfullpath)
(namespace_checkfullpath): Return the namespace number in the last
argument (if not null).
* imap4d/append.c, imap4d/copy.c, imap4d/delete.c, imap4d/list.c,
imap4d/rename.c, imap4d/select.c, imap4d/status.c: Update calls to
namespace_getfullpath.
* imap4d/create.c (imap4d_create): Set mailbox flags depending on
the namespace it is created in.
* imap4d/imap4d.c (mailbox_mode): New variable.
(parse_mode_spec): New function.
(imap4d_cfg_param): New statements other-mailbox-mode and
shared-mailbox-mode.
* imap4d/imap4d.h (mailbox_mode): New proto.
(namespace_getfullpath, namespace_checkfullpath): Add a parameter.

* mailbox/progmailer.c (mu_progmailer_set_debug): Add missing
return statement.
1 parent 1c2596eb
1 2008-11-07 Sergey Poznyakoff <gray@gnu.org.ua>
2
3 Allow to set file permissions of the local mailboxes during
4 creation.
5
6 * include/mailutils/stream.h (MU_STREAM_IRGRP, MU_STREAM_IWGRP)
7 (MU_STREAM_IROTH, MU_STREAM_IWOTH, MU_STREAM_IMASK): New defines.
8 * include/mailutils/mutil.h (mu_stream_flags_to_mode): New
9 prototype.
10 * libproto/maildir/mbox.c (maildir_create, maildir_flush)
11 (maildir_scan0): Consider mailbox flags to determine its file
12 mode.
13 * mailbox/amd.c (amd_open, amd_message_stream_open): Likewise.
14 * mailbox/file_stream.c (_file_open): Likewise.
15 * mailbox/mutil.c (mu_stream_flags_to_mode): New file.
16
17 * imap4d/namespace.c (namespace_getfullpath)
18 (namespace_checkfullpath): Return the namespace number in the last
19 argument (if not null).
20 * imap4d/append.c, imap4d/copy.c, imap4d/delete.c, imap4d/list.c,
21 imap4d/rename.c, imap4d/select.c, imap4d/status.c: Update calls to
22 namespace_getfullpath.
23 * imap4d/create.c (imap4d_create): Set mailbox flags depending on
24 the namespace it is created in.
25 * imap4d/imap4d.c (mailbox_mode): New variable.
26 (parse_mode_spec): New function.
27 (imap4d_cfg_param): New statements other-mailbox-mode and
28 shared-mailbox-mode.
29 * imap4d/imap4d.h (mailbox_mode): New proto.
30 (namespace_getfullpath, namespace_checkfullpath): Add a parameter.
31
32 * mailbox/progmailer.c (mu_progmailer_set_debug): Add missing
33 return statement.
34
1 2008-11-05 Sergey Poznyakoff <gray@gnu.org.ua> 35 2008-11-05 Sergey Poznyakoff <gray@gnu.org.ua>
2 36
3 Implement forwarding functionality in Maidag. 37 Implement forwarding functionality in Maidag.
......
...@@ -182,7 +182,7 @@ imap4d_append (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -182,7 +182,7 @@ imap4d_append (struct imap4d_command *command, imap4d_tokbuf_t tok)
182 182
183 msg_text = imap4d_tokbuf_getarg (tok, i); 183 msg_text = imap4d_tokbuf_getarg (tok, i);
184 184
185 mboxname = namespace_getfullpath (mboxname, "/"); 185 mboxname = namespace_getfullpath (mboxname, "/", NULL);
186 if (!mboxname) 186 if (!mboxname)
187 return util_finish (command, RESP_NO, "Couldn't open mailbox"); 187 return util_finish (command, RESP_NO, "Couldn't open mailbox");
188 188
......
...@@ -87,7 +87,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) ...@@ -87,7 +87,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
87 return RESP_OK; 87 return RESP_OK;
88 } 88 }
89 89
90 mailbox_name = namespace_getfullpath (name, delim); 90 mailbox_name = namespace_getfullpath (name, delim, NULL);
91 91
92 if (!mailbox_name) 92 if (!mailbox_name)
93 { 93 {
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
21 21
22 #define MKDIR_PERMISSIONS 0700 22 #define MKDIR_PERMISSIONS 0700
23 23
24 /* FIXME: take permissions as argument */
24 static int 25 static int
25 mkdir_p (char *name, int delim) 26 mkdir_p (char *name, int delim)
26 { 27 {
...@@ -84,6 +85,7 @@ imap4d_create (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -84,6 +85,7 @@ imap4d_create (struct imap4d_command *command, imap4d_tokbuf_t tok)
84 char *name; 85 char *name;
85 const char *delim = "/"; 86 const char *delim = "/";
86 int isdir = 0; 87 int isdir = 0;
88 int ns;
87 int rc = RESP_OK; 89 int rc = RESP_OK;
88 const char *msg = "Completed"; 90 const char *msg = "Completed";
89 91
...@@ -111,7 +113,7 @@ imap4d_create (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -111,7 +113,7 @@ imap4d_create (struct imap4d_command *command, imap4d_tokbuf_t tok)
111 isdir = 1; 113 isdir = 1;
112 114
113 /* Allocates memory. */ 115 /* Allocates memory. */
114 name = namespace_getfullpath (name, delim); 116 name = namespace_getfullpath (name, delim, &ns);
115 117
116 if (!name) 118 if (!name)
117 return util_finish (command, RESP_NO, "Cannot create mailbox"); 119 return util_finish (command, RESP_NO, "Cannot create mailbox");
...@@ -139,7 +141,8 @@ imap4d_create (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -139,7 +141,8 @@ imap4d_create (struct imap4d_command *command, imap4d_tokbuf_t tok)
139 msg = "Cannot create mailbox"; 141 msg = "Cannot create mailbox";
140 } 142 }
141 else if ((rc = mu_mailbox_open (mbox, 143 else if ((rc = mu_mailbox_open (mbox,
142 MU_STREAM_RDWR|MU_STREAM_CREAT))) 144 MU_STREAM_RDWR | MU_STREAM_CREAT
145 | mailbox_mode[ns])))
143 { 146 {
144 mu_diag_output (MU_DIAG_ERR, 147 mu_diag_output (MU_DIAG_ERR,
145 _("Cannot open mailbox %s: %s"), 148 _("Cannot open mailbox %s: %s"),
......
...@@ -49,7 +49,7 @@ imap4d_delete (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -49,7 +49,7 @@ imap4d_delete (struct imap4d_command *command, imap4d_tokbuf_t tok)
49 return util_finish (command, RESP_NO, "Already exist"); 49 return util_finish (command, RESP_NO, "Already exist");
50 50
51 /* Allocates memory. */ 51 /* Allocates memory. */
52 name = namespace_getfullpath (name, delim); 52 name = namespace_getfullpath (name, delim, NULL);
53 if (!name) 53 if (!name)
54 return util_finish (command, RESP_NO, "Cannot remove"); 54 return util_finish (command, RESP_NO, "Cannot remove");
55 55
......
...@@ -39,6 +39,8 @@ int create_home_dir; /* Create home directory if it does not ...@@ -39,6 +39,8 @@ int create_home_dir; /* Create home directory if it does not
39 exist */ 39 exist */
40 int home_dir_mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; 40 int home_dir_mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
41 41
42 int mailbox_mode[NS_MAX];
43
42 /* Saved command line. */ 44 /* Saved command line. */
43 int imap4d_argc; 45 int imap4d_argc;
44 char **imap4d_argv; 46 char **imap4d_argv;
...@@ -282,6 +284,106 @@ cb_preauth (mu_debug_t debug, void *data, mu_config_value_t *val) ...@@ -282,6 +284,106 @@ cb_preauth (mu_debug_t debug, void *data, mu_config_value_t *val)
282 return 0; 284 return 0;
283 } 285 }
284 286
287 #define FILE_MODE_READ 0x1
288 #define FILE_MODE_WRITE 0x2
289
290 static int
291 parse_mode_bits (int *pmode, const char *str, const char **endp)
292 {
293 switch (*str)
294 {
295 case '+':
296 case '=':
297 str++;
298 break;
299
300 default:
301 *endp = str;
302 return 1;
303 }
304
305 for (; *str; str++)
306 {
307 switch (*str)
308 {
309 case 'r':
310 *pmode |= FILE_MODE_READ;
311 break;
312
313 case 'w':
314 *pmode |= FILE_MODE_WRITE;
315 break;
316
317 case ',':
318 *endp = str;
319 return 0;
320
321 default:
322 *endp = str;
323 return 1;
324 }
325 }
326 *endp = str;
327 return 0;
328 }
329
330 static int
331 parse_mode_spec (int *pmode, const char *str, const char **endp)
332 {
333 int mode = 0;
334 int f;
335 while (*str)
336 {
337 switch (*str)
338 {
339 case 'g':
340 if (parse_mode_bits (&f, str + 1, &str))
341 {
342 *endp = str;
343 return 1;
344 }
345 if (f & FILE_MODE_READ)
346 mode |= MU_STREAM_IRGRP;
347 if (f & FILE_MODE_WRITE)
348 mode |= MU_STREAM_IWGRP;
349 break;
350
351 case 'o':
352 if (parse_mode_bits (&f, str + 1, &str))
353 {
354 *endp = str;
355 return 1;
356 }
357 if (f & FILE_MODE_READ)
358 mode |= MU_STREAM_IROTH;
359 if (f & FILE_MODE_WRITE)
360 mode |= MU_STREAM_IWOTH;
361 break;
362
363 default:
364 *endp = str;
365 return 1;
366 }
367 if (*str == ',')
368 str++;
369 }
370 *pmode = mode;
371 *endp = str;
372 return 0;
373 }
374
375 static int
376 cb_mailbox_mode (mu_debug_t debug, void *data, mu_config_value_t *val)
377 {
378 char *p;
379 if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug))
380 return 1;
381 if (parse_mode_spec ((int *)data, val->v.string, &p))
382 mu_cfg_format_error (debug, MU_DEBUG_ERROR,
383 _("invalid mode string near %s"), p);
384 return 0;
385 }
386
285 static struct mu_cfg_param imap4d_cfg_param[] = { 387 static struct mu_cfg_param imap4d_cfg_param[] = {
286 { "other-namespace", MU_CFG_LIST_OF(mu_cfg_string), &namespace[NS_OTHER], 388 { "other-namespace", MU_CFG_LIST_OF(mu_cfg_string), &namespace[NS_OTHER],
287 0, NULL, 389 0, NULL,
...@@ -289,6 +391,12 @@ static struct mu_cfg_param imap4d_cfg_param[] = { ...@@ -289,6 +391,12 @@ static struct mu_cfg_param imap4d_cfg_param[] = {
289 { "shared-namespace", MU_CFG_LIST_OF(mu_cfg_string), &namespace[NS_SHARED], 391 { "shared-namespace", MU_CFG_LIST_OF(mu_cfg_string), &namespace[NS_SHARED],
290 0, NULL, 392 0, NULL,
291 N_("Set shared namespace.") }, 393 N_("Set shared namespace.") },
394 { "other-mailbox-mode", mu_cfg_callback, &mailbox_mode[NS_OTHER], 0,
395 cb_mailbox_mode,
396 N_("File mode for mailboxes in other namespace.") },
397 { "shared-mailbox-mode", mu_cfg_callback, &mailbox_mode[NS_SHARED], 0,
398 cb_mailbox_mode,
399 N_("File mode for mailboxes in shared namespace.") },
292 { "login-disabled", mu_cfg_bool, &login_disabled, 0, NULL, 400 { "login-disabled", mu_cfg_bool, &login_disabled, 0, NULL,
293 N_("Disable LOGIN command.") }, 401 N_("Disable LOGIN command.") },
294 { "create-home-dir", mu_cfg_bool, &create_home_dir, 0, NULL, 402 { "create-home-dir", mu_cfg_bool, &create_home_dir, 0, NULL,
......
...@@ -182,6 +182,8 @@ extern int is_virtual; ...@@ -182,6 +182,8 @@ extern int is_virtual;
182 extern struct mu_auth_data *auth_data; 182 extern struct mu_auth_data *auth_data;
183 extern const char *program_version; 183 extern const char *program_version;
184 184
185 extern int mailbox_mode[NS_MAX];
186
185 extern int login_disabled; 187 extern int login_disabled;
186 extern int tls_required; 188 extern int tls_required;
187 extern enum imap4d_preauth preauth_mode; 189 extern enum imap4d_preauth preauth_mode;
...@@ -281,9 +283,9 @@ extern mu_list_t namespace[NS_MAX]; ...@@ -281,9 +283,9 @@ extern mu_list_t namespace[NS_MAX];
281 283
282 extern int namespace_init_session (char *path); 284 extern int namespace_init_session (char *path);
283 extern void namespace_init (void); 285 extern void namespace_init (void);
284 extern char * namespace_getfullpath (char *name, const char *delim); 286 extern char *namespace_getfullpath (char *name, const char *delim, int *pns);
285 extern char * namespace_checkfullpath (char *name, const char *pattern, 287 extern char *namespace_checkfullpath (char *name, const char *pattern,
286 const char *delim); 288 const char *delim, int *pns);
287 int imap4d_session_setup (char *username); 289 int imap4d_session_setup (char *username);
288 int imap4d_session_setup0 (void); 290 int imap4d_session_setup0 (void);
289 291
......
...@@ -229,7 +229,7 @@ imap4d_list (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -229,7 +229,7 @@ imap4d_list (struct imap4d_command *command, imap4d_tokbuf_t tok)
229 } 229 }
230 230
231 /* Allocates. */ 231 /* Allocates. */
232 cwd = namespace_checkfullpath (ref, wcard, delim); 232 cwd = namespace_checkfullpath (ref, wcard, delim, NULL);
233 if (!cwd) 233 if (!cwd)
234 { 234 {
235 free (ref); 235 free (ref);
......
...@@ -166,7 +166,8 @@ risky_pattern (const char *pattern, int delim) ...@@ -166,7 +166,8 @@ risky_pattern (const char *pattern, int delim)
166 } 166 }
167 167
168 char * 168 char *
169 namespace_checkfullpath (char *name, const char *pattern, const char *delim) 169 namespace_checkfullpath (char *name, const char *pattern, const char *delim,
170 int *nspace)
170 { 171 {
171 struct namespace_info info; 172 struct namespace_info info;
172 char *p, *path = NULL; 173 char *p, *path = NULL;
...@@ -207,6 +208,8 @@ namespace_checkfullpath (char *name, const char *pattern, const char *delim) ...@@ -207,6 +208,8 @@ namespace_checkfullpath (char *name, const char *pattern, const char *delim)
207 return NULL; 208 return NULL;
208 } 209 }
209 210
211 if (nspace)
212 *nspace = info.ns;
210 if (scheme) 213 if (scheme)
211 { 214 {
212 char *pathstr = malloc (strlen (scheme) + strlen (path) + 2); 215 char *pathstr = malloc (strlen (scheme) + strlen (path) + 2);
...@@ -223,12 +226,16 @@ namespace_checkfullpath (char *name, const char *pattern, const char *delim) ...@@ -223,12 +226,16 @@ namespace_checkfullpath (char *name, const char *pattern, const char *delim)
223 } 226 }
224 227
225 char * 228 char *
226 namespace_getfullpath (char *name, const char *delim) 229 namespace_getfullpath (char *name, const char *delim, int *nspace)
227 { 230 {
228 if (strcasecmp (name, "INBOX") == 0 && auth_data->change_uid) 231 if (strcasecmp (name, "INBOX") == 0 && auth_data->change_uid)
232 {
229 name = strdup (auth_data->mailbox); 233 name = strdup (auth_data->mailbox);
234 if (nspace)
235 *nspace = NS_PRIVATE;
236 }
230 else 237 else
231 name = namespace_checkfullpath (name, NULL, delim); 238 name = namespace_checkfullpath (name, NULL, delim, nspace);
232 return name; 239 return name;
233 } 240 }
234 241
......
...@@ -55,7 +55,7 @@ imap4d_rename (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -55,7 +55,7 @@ imap4d_rename (struct imap4d_command *command, imap4d_tokbuf_t tok)
55 return util_finish (command, RESP_NO, "Name Inbox is reservered"); 55 return util_finish (command, RESP_NO, "Name Inbox is reservered");
56 56
57 /* Allocates memory. */ 57 /* Allocates memory. */
58 newname = namespace_getfullpath (newname, delim); 58 newname = namespace_getfullpath (newname, delim, NULL);
59 if (!newname) 59 if (!newname)
60 return util_finish (command, RESP_NO, "Permission denied"); 60 return util_finish (command, RESP_NO, "Permission denied");
61 61
...@@ -122,7 +122,7 @@ imap4d_rename (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -122,7 +122,7 @@ imap4d_rename (struct imap4d_command *command, imap4d_tokbuf_t tok)
122 return util_finish (command, RESP_OK, "Already exist"); 122 return util_finish (command, RESP_OK, "Already exist");
123 } 123 }
124 124
125 oldname = namespace_getfullpath (oldname, delim); 125 oldname = namespace_getfullpath (oldname, delim, NULL);
126 126
127 /* It must exist. */ 127 /* It must exist. */
128 if (!oldname || rename (oldname, newname) != 0) 128 if (!oldname || rename (oldname, newname) != 0)
......
...@@ -57,7 +57,7 @@ imap4d_select0 (struct imap4d_command *command, const char *mboxname, ...@@ -57,7 +57,7 @@ imap4d_select0 (struct imap4d_command *command, const char *mboxname,
57 57
58 if (strcmp (mboxname, "INBOX") == 0) 58 if (strcmp (mboxname, "INBOX") == 0)
59 flags |= MU_STREAM_CREAT; 59 flags |= MU_STREAM_CREAT;
60 mailbox_name = namespace_getfullpath (mboxname, "/"); 60 mailbox_name = namespace_getfullpath (mboxname, "/", NULL);
61 61
62 if (!mailbox_name) 62 if (!mailbox_name)
63 return util_finish (command, RESP_NO, "Couldn't open mailbox"); 63 return util_finish (command, RESP_NO, "Couldn't open mailbox");
......
...@@ -82,7 +82,7 @@ imap4d_status (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -82,7 +82,7 @@ imap4d_status (struct imap4d_command *command, imap4d_tokbuf_t tok)
82 82
83 name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); 83 name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
84 84
85 mailbox_name = namespace_getfullpath (name, delim); 85 mailbox_name = namespace_getfullpath (name, delim, NULL);
86 86
87 if (!mailbox_name) 87 if (!mailbox_name)
88 return util_finish (command, RESP_NO, "Error opening mailbox"); 88 return util_finish (command, RESP_NO, "Error opening mailbox");
......
...@@ -155,6 +155,9 @@ extern size_t mu_strftime (char *s, size_t max, const char *format, ...@@ -155,6 +155,9 @@ extern size_t mu_strftime (char *s, size_t max, const char *format,
155 extern int mutil_parse_field_map (const char *map, mu_assoc_t *passoc_tab, 155 extern int mutil_parse_field_map (const char *map, mu_assoc_t *passoc_tab,
156 int *perr); 156 int *perr);
157 157
158 extern int mu_stream_flags_to_mode (int flags);
159
160
158 #ifdef __cplusplus 161 #ifdef __cplusplus
159 } 162 }
160 #endif 163 #endif
......
...@@ -42,6 +42,12 @@ extern "C" { /*}*/ ...@@ -42,6 +42,12 @@ extern "C" { /*}*/
42 /* This one affects only mailboxes */ 42 /* This one affects only mailboxes */
43 #define MU_STREAM_QACCESS 0x00000800 43 #define MU_STREAM_QACCESS 0x00000800
44 44
45 #define MU_STREAM_IRGRP 0x00001000
46 #define MU_STREAM_IWGRP 0x00002000
47 #define MU_STREAM_IROTH 0x00004000
48 #define MU_STREAM_IWOTH 0x00008000
49 #define MU_STREAM_IMASK 0x0000F000
50
45 /* Functions useful to users of the pre-defined stream types. */ 51 /* Functions useful to users of the pre-defined stream types. */
46 52
47 extern int mu_file_stream_create (mu_stream_t *stream, const char* filename, 53 extern int mu_file_stream_create (mu_stream_t *stream, const char* filename,
......
...@@ -433,7 +433,9 @@ maildir_create (struct _amd_data *amd, int flags) ...@@ -433,7 +433,9 @@ maildir_create (struct _amd_data *amd, int flags)
433 { 433 {
434 DIR *dir; 434 DIR *dir;
435 char *tmpname = maildir_mkfilename (amd->name, dirs[i], NULL); 435 char *tmpname = maildir_mkfilename (amd->name, dirs[i], NULL);
436 int rc = maildir_opendir (&dir, tmpname, PERMS); 436 int rc = maildir_opendir (&dir, tmpname,
437 PERMS |
438 mu_stream_flags_to_mode (amd->mailbox->flags));
437 if (rc) 439 if (rc)
438 return rc; 440 return rc;
439 closedir (dir); 441 closedir (dir);
...@@ -525,7 +527,8 @@ maildir_flush (struct _amd_data *amd) ...@@ -525,7 +527,8 @@ maildir_flush (struct _amd_data *amd)
525 struct dirent *entry; 527 struct dirent *entry;
526 char *tmpname = maildir_mkfilename (amd->name, TMPSUF, NULL); 528 char *tmpname = maildir_mkfilename (amd->name, TMPSUF, NULL);
527 529
528 rc = maildir_opendir (&dir, tmpname, PERMS); 530 rc = maildir_opendir (&dir, tmpname,
531 PERMS | mu_stream_flags_to_mode (amd->mailbox->flags));
529 if (rc) 532 if (rc)
530 { 533 {
531 free (tmpname); 534 free (tmpname);
...@@ -664,7 +667,8 @@ maildir_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED, ...@@ -664,7 +667,8 @@ maildir_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED,
664 /* 2nd phase: Scan and deliver messages from new */ 667 /* 2nd phase: Scan and deliver messages from new */
665 name = maildir_mkfilename (amd->name, NEWSUF, NULL); 668 name = maildir_mkfilename (amd->name, NEWSUF, NULL);
666 669
667 status = maildir_opendir (&dir, name, PERMS); 670 status = maildir_opendir (&dir, name,
671 PERMS | mu_stream_flags_to_mode (mailbox->flags));
668 if (status == 0) 672 if (status == 0)
669 { 673 {
670 maildir_deliver_new (amd, dir); 674 maildir_deliver_new (amd, dir);
...@@ -674,7 +678,8 @@ maildir_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED, ...@@ -674,7 +678,8 @@ maildir_scan0 (mu_mailbox_t mailbox, size_t msgno MU_ARG_UNUSED,
674 678
675 name = maildir_mkfilename (amd->name, CURSUF, NULL); 679 name = maildir_mkfilename (amd->name, CURSUF, NULL);
676 /* 3rd phase: Scan cur/ */ 680 /* 3rd phase: Scan cur/ */
677 status = maildir_opendir (&dir, name, PERMS); 681 status = maildir_opendir (&dir, name,
682 PERMS | mu_stream_flags_to_mode (mailbox->flags));
678 if (status == 0) 683 if (status == 0)
679 { 684 {
680 status = maildir_scan_dir (amd, dir, CURSUF); 685 status = maildir_scan_dir (amd, dir, CURSUF);
......
...@@ -337,7 +337,8 @@ amd_open (mu_mailbox_t mailbox, int flags) ...@@ -337,7 +337,8 @@ amd_open (mu_mailbox_t mailbox, int flags)
337 { 337 {
338 int rc; 338 int rc;
339 339
340 if (mkdir (amd->name, S_IRUSR|S_IWUSR|S_IXUSR)) 340 if (mkdir (amd->name,
341 S_IRUSR|S_IWUSR|S_IXUSR|mu_stream_flags_to_mode (flags)))
341 return errno; 342 return errno;
342 if (stat (amd->name, &st) < 0) 343 if (stat (amd->name, &st) < 0)
343 return errno; 344 return errno;
...@@ -1453,6 +1454,7 @@ amd_message_stream_open (struct _amd_message *mhm) ...@@ -1453,6 +1454,7 @@ amd_message_stream_open (struct _amd_message *mhm)
1453 flags |= MU_STREAM_RDWR; 1454 flags |= MU_STREAM_RDWR;
1454 else 1455 else
1455 flags |= MU_STREAM_READ; 1456 flags |= MU_STREAM_READ;
1457 flags |= (amd->mailbox->flags & MU_STREAM_IMASK);
1456 status = mu_file_stream_create (&mhm->stream, filename, flags); 1458 status = mu_file_stream_create (&mhm->stream, filename, flags);
1457 1459
1458 free (filename); 1460 free (filename);
......
...@@ -487,7 +487,8 @@ _file_open (mu_stream_t stream) ...@@ -487,7 +487,8 @@ _file_open (mu_stream_t stream)
487 if (errno != ENOENT) 487 if (errno != ENOENT)
488 return errno; 488 return errno;
489 /* Race condition here when creating the file ??. */ 489 /* Race condition here when creating the file ??. */
490 fd = open (filename, flg|O_CREAT|O_EXCL, 0600); 490 fd = open (filename, flg|O_CREAT|O_EXCL,
491 0600 | mu_stream_flags_to_mode (flags));
491 if (fd < 0) 492 if (fd < 0)
492 return errno; 493 return errno;
493 } 494 }
......
...@@ -33,8 +33,8 @@ ...@@ -33,8 +33,8 @@
33 #include <unistd.h> 33 #include <unistd.h>
34 #include <ctype.h> 34 #include <ctype.h>
35 #include <sys/param.h> 35 #include <sys/param.h>
36 #include <sys/stat.h>
37 #include <sys/types.h> 36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <sys/time.h> 38 #include <sys/time.h>
39 #include <sys/wait.h> 39 #include <sys/wait.h>
40 #include <sys/select.h> 40 #include <sys/select.h>
...@@ -1490,3 +1490,17 @@ mu_sql_decode_password_type (const char *arg, enum mu_password_type *t) ...@@ -1490,3 +1490,17 @@ mu_sql_decode_password_type (const char *arg, enum mu_password_type *t)
1490 return 0; 1490 return 0;
1491 } 1491 }
1492 1492
1493 int
1494 mu_stream_flags_to_mode (int flags)
1495 {
1496 int mode = 0;
1497 if (flags & MU_STREAM_IRGRP)
1498 mode |= S_IRGRP;
1499 if (flags & MU_STREAM_IWGRP)
1500 mode |= S_IWGRP;
1501 if (flags & MU_STREAM_IROTH)
1502 mode |= S_IROTH;
1503 if (flags & MU_STREAM_IWOTH)
1504 mode |= S_IWOTH;
1505 return mode;
1506 }
......
...@@ -99,6 +99,7 @@ mu_progmailer_set_debug (mu_progmailer_t pm, mu_debug_t debug) ...@@ -99,6 +99,7 @@ mu_progmailer_set_debug (mu_progmailer_t pm, mu_debug_t debug)
99 if (!pm) 99 if (!pm)
100 return EINVAL; 100 return EINVAL;
101 pm->debug = debug; 101 pm->debug = debug;
102 return 0;
102 } 103 }
103 104
104 void 105 void
......