1 /*
2 ** Copyright 2003 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5 
6 
7 #if	HAVE_CONFIG_H
8 #include	"config.h"
9 #endif
10 #include	<stdio.h>
11 #include	<string.h>
12 #include	<stdlib.h>
13 #if	HAVE_FCNTL_H
14 #include	<fcntl.h>
15 #endif
16 #if	HAVE_UNISTD_H
17 #include	<unistd.h>
18 #endif
19 #include	<sys/types.h>
20 #if	HAVE_SYS_STAT_H
21 #include	<sys/stat.h>
22 #endif
23 #include	<ctype.h>
24 #include	<errno.h>
25 
26 #include	"maildirmisc.h"
27 #include	"maildiraclt.h"
28 
29 static const char resetcmd[]="-reset";
30 static const char listcmd[]="-list";
31 static const char setcmd[]="-set";
32 static const char deletecmd[]="-delete";
33 static const char computecmd[]="-compute";
34 
usage()35 static void usage()
36 {
37 	printf("Usage: maildiracl [ options ] maildir [INBOX[.folder] [identifier rights]]\n");
38 	exit(1);
39 }
40 
acl_list(const char * identifier,const maildir_aclt * acl,void * cb_arg)41 static int acl_list(const char *identifier,
42 		    const maildir_aclt *acl,
43 		    void *cb_arg)
44 {
45 	printf("%s\t%s\n", identifier, maildir_aclt_ascstr(acl));
46 	return (0);
47 }
48 
49 struct computeinfo {
50 	int argc;
51 	char **argv;
52 };
53 
isme(const char * identifier,void * void_arg)54 static int isme(const char *identifier,
55 		void *void_arg)
56 {
57 	struct computeinfo *ci=(struct computeinfo *)void_arg;
58 	int i;
59 
60 	for (i=4; i<ci->argc; i++)
61 		if (strcmp(ci->argv[i], identifier) == 0)
62 			return 1;
63 	return 0;
64 }
65 
main(int argc,char * argv[])66 int main(int argc, char *argv[])
67 {
68 	const char *cmd;
69 	const char *maildir;
70 	const char *folder;
71 
72 	if (argc < 3)
73 		usage();
74 
75 	cmd=argv[1];
76 
77 	if (strcmp(cmd, resetcmd) &&
78 	    strcmp(cmd, listcmd) &&
79 	    strcmp(cmd, setcmd) &&
80 	    strcmp(cmd, deletecmd) &&
81 	    strcmp(cmd, computecmd))
82 		usage();
83 
84 	maildir=argv[2];
85 
86 	if (strcmp(cmd, resetcmd) == 0)
87 	{
88 		if (maildir_acl_reset(maildir))
89 		{
90 			perror(maildir);
91 			exit(1);
92 		}
93 		exit(0);
94 	}
95 
96 	if (argc < 4)
97 		usage();
98 
99 	folder=argv[3];
100 
101 	if (strcmp(folder, INBOX) &&
102 	    strncmp(folder, INBOX ".", sizeof(INBOX ".")-1))
103 	{
104 		errno=EINVAL;
105 		perror(folder);
106 		exit(1);
107 	}
108 	folder += sizeof(INBOX)-1;
109 
110 	if (!*folder)
111 		folder=".";
112 
113 	if (strcmp(cmd, listcmd) == 0)
114 	{
115 		maildir_aclt_list l;
116 
117 		if (maildir_acl_read(&l, maildir, folder) ||
118 		    maildir_aclt_list_enum(&l, acl_list, NULL))
119 		{
120 			perror(maildir);
121 			exit(1);
122 		}
123 
124 		maildir_aclt_list_destroy(&l);
125 		exit(0);
126 	}
127 
128 	if (strcmp(cmd, setcmd) == 0)
129 	{
130 		maildir_aclt_list l;
131 		maildir_aclt a;
132 
133 		const char *identifier;
134 		const char *rights;
135 		const char *err_failedrights;
136 
137 		if (argc < 6)
138 			usage();
139 
140 		identifier=argv[4];
141 		rights=argv[5];
142 
143 		if (maildir_acl_read(&l, maildir, folder))
144 		{
145 			perror(maildir);
146 			exit(1);
147 		}
148 
149 		if (*rights == '+')
150 		{
151 			if (maildir_aclt_init(&a, NULL,
152 					      maildir_aclt_list_find(&l,
153 								     identifier
154 								     )) ||
155 			    maildir_aclt_add(&a, rights+1, NULL))
156 			{
157 				perror(argv[0]);
158 				exit(1);
159 			}
160 		} else if (*rights == '-')
161 		{
162 			if (maildir_aclt_init(&a, NULL,
163 					      maildir_aclt_list_find(&l,
164 								     identifier
165 								     )) ||
166 			    maildir_aclt_del(&a, rights+1, NULL))
167 			{
168 				perror(argv[0]);
169 				exit(1);
170 			}
171 		}
172 		else if (maildir_aclt_init(&a, rights, NULL))
173 		{
174 			perror(argv[0]);
175 			exit (1);
176 		}
177 
178 		if (maildir_aclt_list_add(&l, identifier, NULL, &a))
179 		{
180 			perror(argv[0]);
181 			exit(1);
182 		}
183 
184 		if (maildir_acl_write(&l, maildir, folder, "owner",
185 				      &err_failedrights))
186 		{
187 			if (err_failedrights)
188 			{
189 				fprintf(stderr,
190 					"Trying to set invalid access"
191 					" rights for %s\n",
192 					err_failedrights);
193 			}
194 			else perror(maildir);
195 			exit(1);
196 		}
197 	}
198 
199 	if (strcmp(cmd, deletecmd) == 0)
200 	{
201 		maildir_aclt_list l;
202 		const char *identifier;
203 		const char *err_failedrights;
204 
205 		if (argc < 5)
206 			usage();
207 
208 		identifier=argv[4];
209 
210 		if (maildir_acl_read(&l, maildir, folder))
211 		{
212 			perror(maildir);
213 			exit(1);
214 		}
215 
216 		if (maildir_aclt_list_del(&l, identifier))
217 		{
218 			perror(maildir);
219 			exit(1);
220 		}
221 
222 		if (maildir_acl_write(&l, maildir, folder, "owner",
223 				      &err_failedrights))
224 		{
225 			if (err_failedrights)
226 			{
227 				fprintf(stderr,
228 					"Trying to set invalid access"
229 					" rights for %s\n",
230 					err_failedrights);
231 			}
232 			else perror(maildir);
233 			exit(1);
234 		}
235 	}
236 
237 	if (strcmp(cmd, computecmd) == 0)
238 	{
239 		maildir_aclt_list l;
240 		maildir_aclt a;
241 
242 		struct computeinfo ci;
243 
244 		ci.argc=argc;
245 		ci.argv=argv;
246 
247 		if (argc < 5)
248 			usage();
249 
250 		if (maildir_acl_read(&l, maildir, folder))
251 		{
252 			perror(maildir);
253 			exit(1);
254 		}
255 
256 		if (maildir_acl_compute(&a, &l, isme, &ci))
257 		{
258 			perror(maildir);
259 			exit(1);
260 		}
261 
262 		printf("%s\n", maildir_aclt_ascstr(&a));
263 	}
264 
265 	return (0);
266 }
267