Example #1
0
int mailbox_scan(const char *reference, const char *name,
		 int list_options,
		 int (*callback_func)(const char *hiersep,
				      const char *mailbox,
				      int flags,
				      void *void_arg),
		 void *void_arg)
{
	char	*pattern, *p;
	int	nullname= *name == 0;
	int	rc;

	pattern=malloc(strlen(reference)+strlen(name)+2);

	strcpy(pattern, reference);

	p=strrchr(pattern, HIERCH);
	if (p && p[1] == 0)	*p=0; /* Strip trailing . for now */
	if (*pattern)
	{
		struct maildir_info mi;

		if (maildir_info_imap_find(&mi, pattern,
					   getenv("AUTHENTICATED")))
		{
			free(pattern);
			return (0); /* Invalid reference */
		}
		maildir_info_destroy(&mi);
	}

	/* Combine reference and name. */
	if (*pattern && *name)
		strcat(pattern, hierchs);
	strcat(pattern, name);

	if (name && *name)
	{
	char *s=strrchr(pattern, HIERCH);

		if (s && s[1] == 0)	*s=0;	/* strip trailing . */

	}

	/* Now, do the list */

	rc=do_mailbox_list(list_options, pattern, nullname,
			   callback_func, void_arg);
	free(pattern);
	return (rc);
}
Example #2
0
int acl_read(maildir_aclt_list *l, const char *folder,
	     char **owner)
{
	struct maildir_info minfo;
	int rc;

	if (maildir_info_imap_find(&minfo, folder,
				   login_returnaddr())<0)
	{
		return -1;
	}

	rc=acl_read2(l, &minfo, owner);
	maildir_info_destroy(&minfo);
	return rc;
}
Example #3
0
static void doupdate()
{
	maildir_aclt_list l;
	char *owner;
	char buf[2];
	char *p;
	struct maildir_info minfo;

	if (maildir_info_imap_find(&minfo, sqwebmail_folder,
				   login_returnaddr()) < 0)
		return;

	if (acl_read2(&l, &minfo, &owner) < 0)
	{
		maildir_info_destroy(&minfo);
		return;
	}

	strcpy(buf, ACL_ADMINISTER);
	acl_computeRights(&l, buf, owner);
	if (!*buf)
	{
		if (owner)
			free(owner);
		maildir_aclt_list_destroy(&l);
		maildir_info_destroy(&minfo);
		return;
	}

	if (*cgi("delentity"))
	{
		if (maildir_aclt_list_del(&l, cgi("delentity")))
			printf("%s", getarg("ACL_failed"));
	}

	if (*cgi("do.update"))
	{
		char *entity=NULL;
		const char *p;
		char new_acl[40];

		p=cgi("entitytype");

		if (strcmp(p, "anonymous") == 0 ||
		    strcmp(p, "owner") == 0)
			entity=strdup(p);
		else if (strcmp(p, "user") == 0)
		{
			p=cgi("entity");

			if (*p)
			{
				entity=malloc(sizeof("user="******"user="******"group") == 0)
		{
			p=cgi("entity");

			if (*p)
			{
				entity=malloc(sizeof("group=")+strlen(p));
				if (entity)
					strcat(strcpy(entity, "group="), p);
			}
		}
		else
		{
			entity=strdup(cgi("entity"));
		}

		if (*cgi("negate") == '-' && entity)
		{
			char *p=malloc(strlen(entity)+2);

			if (p)
				strcat(strcpy(p, "-"), entity);
			free(entity);
			entity=p;
		}

		if (entity)
		{
			char *val=
				unicode_convert_toutf8(entity,
							 sqwebmail_content_charset,
							 NULL);


			if (val)
			{
				free(entity);
				entity=val;
			}
		}
		p=getarg("ACL_all");

		new_acl[0]=0;

		while (*p && strlen(new_acl) < sizeof(new_acl)-2)
		{
			char b[40];

			sprintf(b, "acl_%c", *p);

			if (*cgi(b))
			{
				b[0]=*p;
				b[1]=0;
				strcat(new_acl, b);
			}
			++p;
		}

		if (!entity || !*entity ||
		    maildir_aclt_list_add(&l, entity, new_acl, NULL) < 0)
			printf("%s", getarg("ACL_failed"));

		if (entity)
			free(entity);
	}

	p=maildir_name2dir(".", minfo.maildir);

	if (p)
	{
		const char *err_ident;

		if (maildir_acl_write(&l, minfo.homedir,
				      strncmp(p, "./", 2) == 0 ? p+2:p,
				      owner, &err_ident))
			printf("%s", getarg("ACL_failed"));
		free(p);
	}

	if (owner)
		free(owner);
	maildir_aclt_list_destroy(&l);
	maildir_info_destroy(&minfo);
}
Example #4
0
void listrights()
{
	maildir_aclt_list l;
	char buf[40];
	char *owner;

	if (*cgi("do.update") || *cgi("delentity"))
	{
		struct maildir_info minfo;

		if (maildir_info_imap_find(&minfo, sqwebmail_folder,
					   login_returnaddr()) == 0)
		{
			if (minfo.homedir)
			{
				struct maildirwatch *w;
				char *lock;
				int tryanyway;

				w=maildirwatch_alloc(minfo.homedir);

				if (!w)
				{
					maildir_info_destroy(&minfo);
					enomem();
					return;
				}

				lock=maildir_lock(minfo.homedir, w,
						  &tryanyway);

				maildir_info_destroy(&minfo);

				if (lock == NULL)
				{
					if (!tryanyway)
					{
						printf("%s",
						       getarg("ACL_noaccess"));
						return;
					}
				}
				doupdate();
				if (lock)
				{
					unlink(lock);
					free(lock);
				}
				maildirwatch_free(w);
			}
		}
	}

	if (acl_read(&l, sqwebmail_folder, &owner) < 0)
	{
		printf("%s", getarg("ACL_cantread"));
		return;
	}
	buf[0]=0;
	strncat(buf, getarg("ACL_all"), sizeof(buf)-2);
	acl_computeRights(&l, buf, owner);
	maildir_aclt_list_destroy(&l);
	if (owner)
		free(owner);

	if (!maildir_acl_canlistrights(buf))
	{
		printf("%s", getarg("ACL_cantread"));
		return;
	}

	showrights(buf);
}
Example #5
0
int maildir_info_imap_find(struct maildir_info *info, const char *path,
			   const char *myId)
{
	const char *p;
	struct imap_find_shared ifs;
	const char *indexfile;
	char *indexfile_cpy;
	struct maildir_shindex_cache *curcache;
	const char *subhierarchy;

	info->homedir=NULL;
	info->maildir=NULL;
	info->owner=NULL;

	if (strchr(path, '/'))
	{
		errno=EINVAL;
		return -1;
	}

	for (p=path; *p; p++)
		if (*p == '.' && p[1] == '.')
		{
			errno=EINVAL;
			return -1;
		}

	if (strncmp(path, SHARED, sizeof(SHARED)-1) == 0)
	{
		path += sizeof(SHARED)-1;

		info->homedir=strdup(".");
		if (!info->homedir)
			return -1;

		info->mailbox_type=MAILBOXTYPE_OLDSHARED;
		info->owner=strdup("anonymous");

		if (!info->owner)
		{
			maildir_info_destroy(info);
			return -1;
		}

		/* We need to specialcase "shared" and "shared.name".
		** maildir_shareddir will return NULL for these cases, because
		** it will insist on "name.folder", but we need to return a
		** non NULL value to indicate that this is a valid hierarchy
		** name.  We return a special value of an empty string, which
		** is checked for in situations where a valid folder is
		** required.
		*/

		if (*path && *path != '.')
		{
			maildir_info_destroy(info);
			errno=EINVAL;
			return -1;
		}

		return 0;
	}

	if (strncasecmp(path, INBOX, sizeof(INBOX)-1) == 0)
	{
		switch (path[sizeof(INBOX)-1]) {
		case 0:
		case '.':
			break;
		default:
			errno=EINVAL;
			return -1;
		}

		info->homedir=strdup(".");

		if (!info->homedir)
			return -1;

		info->maildir=strdup(path);
		if (!info->maildir)
		{
			maildir_info_destroy(info);
			return -1;
		}

		info->owner=malloc(strlen(myId)+sizeof("user="******"user="******"vendor=courier.internal");

	if (!info->owner)
		return -1;

	ifs.homedir=NULL;
	ifs.maildir=NULL;

	indexfile=NULL;
	indexfile_cpy=NULL;
	curcache=NULL;
	subhierarchy=NULL;

	while (*ifs.path)
	{
		int rc, eof;
		size_t i;

		curcache=maildir_shared_cache_read(curcache, indexfile,
						   subhierarchy);

		if (indexfile_cpy)
		{
			free(indexfile_cpy);
			indexfile_cpy=NULL;
		}

		if (!curcache)
			break;

		p=strchr(ifs.path, '.');

		if (p)
			ifs.path_l=p-ifs.path;
		else
			ifs.path_l=strlen(ifs.path);


		if (ifs.homedir)
			free(ifs.homedir);
		if (ifs.maildir)
			free(ifs.maildir);

		ifs.homedir=NULL;
		ifs.maildir=NULL;

		for (i=0; i < curcache->nrecords; i++)
		{
			char *n=maildir_info_imapmunge(curcache->
						       records[i].name);

			if (n == NULL)
			{
				i=curcache->nrecords;
				break;
			}

			if (strlen(n) == ifs.path_l &&
			    strncmp(n, ifs.path, ifs.path_l) == 0)
			{
				free(n);
				break;
			}
			free(n);
		}

		if (i >= curcache->nrecords)
			break;

		curcache->indexfile.startingpos=
			curcache->records[i].offset;
		rc=maildir_newshared_nextAt(&curcache->indexfile,
					    &eof,
					    imap_find_cb, &ifs);

		if (rc || eof)
		{
			fprintf(stderr, "ERR: Internal error -"
				" maildir_newshared_nextAt: %s\n",
				strerror(errno));
			fflush(stderr);
			break;
		}

		if (!ifs.homedir && !ifs.maildir)
			break;

		if (!ifs.homedir)
		{
			indexfile=indexfile_cpy=ifs.maildir;
			ifs.maildir=NULL;
			subhierarchy=curcache->records[i].name;

			ifs.path += ifs.path_l;
			if (*ifs.path)
				++ifs.path;
			continue;
		}

		info->homedir=maildir_location(ifs.homedir,
					     ifs.maildir);

		free(ifs.homedir);
		free(ifs.maildir);

		free(info->owner);

		if (!info->homedir)
		{
			info->maildir=NULL;
			info->owner=NULL;
			return -1;
		}

		if (!subhierarchy || !*subhierarchy)
		{
			info->owner=strdup("vendor=courier.internal");
			if (!info->owner)
			{
				free(info->homedir);
				info->homedir=NULL;
				info->maildir=NULL;
				return -1;
			}
		}
		else
		{
			char *owner_utf8;

			info->owner=malloc(strlen(subhierarchy)
					   +sizeof("user="******"user="******"utf-8", NULL);

			if (!owner_utf8)
			{
				free(info->homedir);
				info->homedir=NULL;
				return (0);
			}

			free(info->owner);
			info->owner=owner_utf8;
		}

		ifs.path += ifs.path_l;

		info->maildir=malloc(strlen(INBOX)+1+strlen(ifs.path));
		if (!info->maildir)
		{
			free(info->owner);
			free(info->homedir);
			info->owner=NULL;
			info->homedir=NULL;
			return -1;
		}
		strcat(strcpy(info->maildir, INBOX), ifs.path);

		if (maildir_info_suppress(info->homedir))
		{

			free(info->homedir);
			free(info->maildir);
			info->homedir=NULL;
			info->maildir=NULL;
			info->mailbox_type=MAILBOXTYPE_IGNORE;
			free(info->owner);
			info->owner=NULL;
			info->owner=strdup("vendor=courier.internal");
			if (!info->owner)
			{
				return -1;
			}
		}

		return 0;
	}

	if (indexfile_cpy)
		free(indexfile_cpy);
	if (ifs.homedir)
	{
		free(ifs.homedir);
		ifs.homedir=NULL;
	}

	if (ifs.maildir)
	{
		free(ifs.maildir);
		ifs.maildir=NULL;
	}
	return 0;
}
Example #6
0
int maildir_info_smap_find(struct maildir_info *info, char **folder,
			   const char *myId)
{
	char *p;
	size_t n;
	const char *indexfile;
	struct maildir_shindex_cache *curcache;
	const char *subhierarchy;
	struct imap_find_shared ifs;
	int rc, eof;
	char *indexfile_cpy=NULL;

	info->homedir=NULL;
	info->maildir=NULL;
	info->owner=NULL;
	info->mailbox_type=MAILBOXTYPE_IGNORE;

	if (folder[0] == NULL)
	{
		errno=EINVAL;
		return -1;
	}

	if (strcmp(folder[0], PUBLIC))
	{
		if (strcmp(folder[0], INBOX))
		{
			errno=EINVAL;
			return -1;
		}

		info->maildir=smap_path(NULL, folder);

		if (info->maildir == NULL)
			return -1;
		info->homedir=strdup(".");
		if (!info->homedir)
		{
			maildir_info_destroy(info);
			return -1;
		}

		info->mailbox_type=MAILBOXTYPE_INBOX;

		info->owner=malloc(strlen(myId)+sizeof("user="******"user="******"ERR: Internal error -"
				" maildir_newshared_nextAt: %s\n",
				strerror(errno));
			fflush(stderr);
			break;
		}

		if (!ifs.homedir && !ifs.maildir)
			break;

		if (!ifs.homedir)
		{
			if (indexfile_cpy)
				free(indexfile_cpy);
			indexfile=indexfile_cpy=ifs.maildir;
			ifs.maildir=NULL;
			subhierarchy=curcache->records[i].name;
			++n;
			continue;
		}

		if (indexfile_cpy)
			free(indexfile_cpy);
		info->homedir=maildir_location(ifs.homedir,
					       ifs.maildir);
		free(ifs.homedir);
		free(ifs.maildir);

		info->maildir=NULL;

		if (maildir_info_suppress(info->homedir))
		{

			free(info->homedir);
			info->homedir=NULL;
			info->maildir=NULL;
			info->mailbox_type=MAILBOXTYPE_IGNORE;
			info->owner=NULL;
			info->owner=strdup("vendor=courier.internal");
			if (!info->owner)
			{
				maildir_info_destroy(info);
				return -1;
			}

			return 0;
		}


		if (!subhierarchy || !*subhierarchy)
		{
			info->owner=strdup("vendor=courier.internal");
			if (!info->owner)
			{
				maildir_info_destroy(info);
				return -1;
			}
		}
		else
		{
			info->owner=malloc(strlen(subhierarchy)
					   +sizeof("user="******"user="******"vendor=courier.internal");
		if (!info->owner)
		{
			maildir_info_destroy(info);
			return -1;
		}

		/* Intermediate shared namespce */
		return 0;
	}

	return -1;
}