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