示例#1
0
/*
 * Cull the database logs
 */
void cdb_cull_logs(void)
{
	u_int32_t flags;
	int ret;
	char **file, **list;
	char errmsg[SIZ];

	flags = DB_ARCH_ABS;

	/* Get the list of names. */
	if ((ret = dbenv->log_archive(dbenv, &list, flags)) != 0) {
		syslog(LOG_ERR, "cdb_cull_logs: %s", db_strerror(ret));
		return;
	}

	/* Print the list of names. */
	if (list != NULL) {
		for (file = list; *file != NULL; ++file) {
			syslog(LOG_DEBUG, "Deleting log: %s", *file);
			ret = unlink(*file);
			if (ret != 0) {
				snprintf(errmsg, sizeof(errmsg),
					 " ** ERROR **\n \n \n "
					 "Citadel was unable to delete the "
					 "database log file '%s' because of the "
					 "following error:\n \n %s\n \n"
					 " This log file is no longer in use "
					 "and may be safely deleted.\n",
					 *file, strerror(errno));
				CtdlAideMessage(errmsg, "Database Warning Message");
			}
		}
		free(list);
	}
}
示例#2
0
/*
 * Administrative Set User Parameters
 */
void cmd_asup(char *cmdbuf)
{
	struct ctdluser usbuf;
	char requested_user[128];
	char notify[SIZ];
	int np;
	int newax;
	int deleted = 0;

	if (CtdlAccessCheck(ac_aide))
		return;

	extract_token(requested_user, cmdbuf, 0, '|', sizeof requested_user);
	if (CtdlGetUserLock(&usbuf, requested_user) != 0) {
		cprintf("%d No such user.\n", ERROR + NO_SUCH_USER);
		return;
	}
	np = num_parms(cmdbuf);
	if (np > 1)
		extract_token(usbuf.password, cmdbuf, 1, '|', sizeof usbuf.password);
	if (np > 2)
		usbuf.flags = extract_int(cmdbuf, 2);
	if (np > 3)
		usbuf.timescalled = extract_int(cmdbuf, 3);
	if (np > 4)
		usbuf.posted = extract_int(cmdbuf, 4);
	if (np > 5) {
		newax = extract_int(cmdbuf, 5);
		if ((newax >= AxDeleted) && (newax <= AxAideU)) {
			usbuf.axlevel = newax;
		}
	}
	if (np > 7) {
		usbuf.lastcall = extract_long(cmdbuf, 7);
	}
	if (np > 8) {
		usbuf.USuserpurge = extract_int(cmdbuf, 8);
	}
	CtdlPutUserLock(&usbuf);
	if (usbuf.axlevel == AxDeleted) {
		if (purge_user(requested_user) == 0) {
			deleted = 1;
		}
	}

	if (deleted) {
		snprintf(notify, SIZ, 
			 "User \"%s\" has been deleted by %s.\n",
			 usbuf.fullname,
			(CC->logged_in ? CC->user.fullname : "an administrator")
		);
		CtdlAideMessage(notify, "User Deletion Message");
	}

	cprintf("%d Ok", CIT_OK);
	if (deleted)
		cprintf(" (%s deleted)", requested_user);
	cprintf("\n");
}
示例#3
0
int PurgeRooms(void) {
	struct PurgeList *pptr;
	int num_rooms_purged = 0;
	struct ctdlroom qrbuf;
	struct ValidUser *vuptr;
	char *transcript = NULL;

	syslog(LOG_DEBUG, "PurgeRooms() called");


	/* Load up a table full of valid user numbers so we can delete
	 * user-owned rooms for users who no longer exist */
	ForEachUser(AddValidUser, NULL);

	/* Then cycle through the room file */
	CtdlForEachRoom(DoPurgeRooms, NULL);

	/* Free the valid user list */
	while (ValidUserList != NULL) {
		vuptr = ValidUserList->next;
		free(ValidUserList);
		ValidUserList = vuptr;
	}


	transcript = malloc(SIZ);
	strcpy(transcript, "The following rooms have been auto-purged:\n");

	while (RoomPurgeList != NULL) {
		if (CtdlGetRoom(&qrbuf, RoomPurgeList->name) == 0) {
			transcript=realloc(transcript, strlen(transcript)+SIZ);
			snprintf(&transcript[strlen(transcript)], SIZ, " %s\n",
				qrbuf.QRname);
			CtdlDeleteRoom(&qrbuf);
		}
		pptr = RoomPurgeList->next;
		free(RoomPurgeList);
		RoomPurgeList = pptr;
		++num_rooms_purged;
	}

	if (num_rooms_purged > 0) CtdlAideMessage(transcript, "Room Autopurger Message");
	free(transcript);

	syslog(LOG_DEBUG, "Purged %d rooms.", num_rooms_purged);
	return(num_rooms_purged);
}
示例#4
0
/*
 * Attach an OpenID to a Citadel account
 */
int attach_openid(struct ctdluser *who, StrBuf *claimed_id)
{
	struct cdbdata *cdboi;
	long fetched_usernum;
	char *data;
	int data_len;
	char buf[2048];

	if (!who) return(1);
	if (StrLength(claimed_id)==0) return(1);

	/* Check to see if this OpenID is already in the database */

	cdboi = cdb_fetch(CDB_OPENID, ChrPtr(claimed_id), StrLength(claimed_id));
	if (cdboi != NULL) {
		memcpy(&fetched_usernum, cdboi->ptr, sizeof(long));
		cdb_free(cdboi);

		if (fetched_usernum == who->usernum) {
			syslog(LOG_INFO, "%s already associated; no action is taken", ChrPtr(claimed_id));
			return(0);
		}
		else {
			syslog(LOG_INFO, "%s already belongs to another user", ChrPtr(claimed_id));
			return(3);
		}
	}

	/* Not already in the database, so attach it now */

	data_len = sizeof(long) + StrLength(claimed_id) + 1;
	data = malloc(data_len);

	memcpy(data, &who->usernum, sizeof(long));
	memcpy(&data[sizeof(long)], ChrPtr(claimed_id), StrLength(claimed_id) + 1);

	cdb_store(CDB_OPENID, ChrPtr(claimed_id), StrLength(claimed_id), data, data_len);
	free(data);

	snprintf(buf, sizeof buf, "User <%s> (#%ld) has claimed the OpenID URL %s\n",
		 who->fullname, who->usernum, ChrPtr(claimed_id));
	CtdlAideMessage(buf, "OpenID claim");
	syslog(LOG_INFO, "%s", buf);
	return(0);
}
示例#5
0
/* 
 * set the room admin for this room
 */
void cmd_seta(char *new_ra)
{
	struct ctdluser usbuf;
	long newu;
	char buf[SIZ];
	int post_notice;

	if (CtdlAccessCheck(ac_room_aide)) return;

	if (CtdlGetUser(&usbuf, new_ra) != 0) {
		newu = (-1L);
	} else {
		newu = usbuf.usernum;
	}

	CtdlGetRoomLock(&CC->room, CC->room.QRname);
	post_notice = 0;
	if (CC->room.QRroomaide != newu) {
		post_notice = 1;
	}
	CC->room.QRroomaide = newu;
	CtdlPutRoomLock(&CC->room);

	/*
	 * We have to post the change notice _after_ writing changes to 
	 * the room table, otherwise it would deadlock!
	 */
	if (post_notice == 1) {
		if (!IsEmptyStr(usbuf.fullname))
			snprintf(buf, sizeof buf,
				"%s is now the room admin for \"%s\".\n",
				usbuf.fullname, CC->room.QRname);
		else
			snprintf(buf, sizeof buf,
				"There is now no room admin for \"%s\".\n",
				CC->room.QRname);
		CtdlAideMessage(buf, "Admin Room Modification");
	}
	cprintf("%d Ok\n", CIT_OK);
}
示例#6
0
/*
 * admin command: kill the current room
 */
void cmd_kill(char *argbuf)
{
	char deleted_room_name[ROOMNAMELEN];
	char msg[SIZ];
	int kill_ok;

	kill_ok = extract_int(argbuf, 0);

	if (CtdlDoIHavePermissionToDeleteThisRoom(&CC->room) == 0) {
		cprintf("%d Can't delete this room.\n", ERROR + NOT_HERE);
		return;
	}
	if (kill_ok) {
		if (CC->room.QRflags & QR_MAILBOX) {
			safestrncpy(deleted_room_name, &CC->room.QRname[11], sizeof deleted_room_name);
		}
		else {
			safestrncpy(deleted_room_name, CC->room.QRname, sizeof deleted_room_name);
		}

		/* Do the dirty work */
		CtdlScheduleRoomForDeletion(&CC->room);

		/* Return to the Lobby */
		CtdlUserGoto(CtdlGetConfigStr("c_baseroom"), 0, 0, NULL, NULL, NULL, NULL);

		/* tell the world what we did */
		snprintf(msg, sizeof msg, "The room \"%s\" has been deleted by %s.\n",
			 deleted_room_name,
			(CC->logged_in ? CC->curr_user : "******")
		);
		CtdlAideMessage(msg, "Room Purger Message");
		cprintf("%d '%s' deleted.\n", CIT_OK, deleted_room_name);
	} else {
		cprintf("%d ok to delete.\n", CIT_OK);
	}
}
示例#7
0
文件: control.c 项目: henri14/citadel
/* 
 * Get or set global configuration options
 *
 * IF YOU ADD OR CHANGE FIELDS HERE, YOU *MUST* DOCUMENT YOUR CHANGES AT:
 * http://www.citadel.org/doku.php?id=documentation:applicationprotocol
 *
 */
void cmd_conf(char *argbuf)
{
	char cmd[16];
	char buf[256];
	int a;
	char *confptr;
	char confname[128];

	if (CtdlAccessCheck(ac_aide)) return;

	extract_token(cmd, argbuf, 0, '|', sizeof cmd);
	if (!strcasecmp(cmd, "GET")) {
		cprintf("%d Configuration...\n", LISTING_FOLLOWS);
		cprintf("%s\n", config.c_nodename);
		cprintf("%s\n", config.c_fqdn);
		cprintf("%s\n", config.c_humannode);
		cprintf("%s\n", config.c_phonenum);
		cprintf("%d\n", config.c_creataide);
		cprintf("%d\n", config.c_sleeping);
		cprintf("%d\n", config.c_initax);
		cprintf("%d\n", config.c_regiscall);
		cprintf("%d\n", config.c_twitdetect);
		cprintf("%s\n", config.c_twitroom);
		cprintf("%s\n", config.c_moreprompt);
		cprintf("%d\n", config.c_restrict);
		cprintf("%s\n", config.c_site_location);
		cprintf("%s\n", config.c_sysadm);
		cprintf("%d\n", config.c_maxsessions);
		cprintf("xxx\n"); /* placeholder -- field no longer in use */
		cprintf("%d\n", config.c_userpurge);
		cprintf("%d\n", config.c_roompurge);
		cprintf("%s\n", config.c_logpages);
		cprintf("%d\n", config.c_createax);
		cprintf("%ld\n", config.c_maxmsglen);
		cprintf("%d\n", config.c_min_workers);
		cprintf("%d\n", config.c_max_workers);
		cprintf("%d\n", config.c_pop3_port);
		cprintf("%d\n", config.c_smtp_port);
		cprintf("%d\n", config.c_rfc822_strict_from);
		cprintf("%d\n", config.c_aide_zap);
		cprintf("%d\n", config.c_imap_port);
		cprintf("%ld\n", config.c_net_freq);
		cprintf("%d\n", config.c_disable_newu);
		cprintf("1\n");	/* niu */
		cprintf("%d\n", config.c_purge_hour);
#ifdef HAVE_LDAP
		cprintf("%s\n", config.c_ldap_host);
		cprintf("%d\n", config.c_ldap_port);
		cprintf("%s\n", config.c_ldap_base_dn);
		cprintf("%s\n", config.c_ldap_bind_dn);
		cprintf("%s\n", config.c_ldap_bind_pw);
#else
		cprintf("\n");
		cprintf("0\n");
		cprintf("\n");
		cprintf("\n");
		cprintf("\n");
#endif
		cprintf("%s\n", config.c_ip_addr);
		cprintf("%d\n", config.c_msa_port);
		cprintf("%d\n", config.c_imaps_port);
		cprintf("%d\n", config.c_pop3s_port);
		cprintf("%d\n", config.c_smtps_port);
		cprintf("%d\n", config.c_enable_fulltext);
		cprintf("%d\n", config.c_auto_cull);
		cprintf("1\n");
		cprintf("%d\n", config.c_allow_spoofing);
		cprintf("%d\n", config.c_journal_email);
		cprintf("%d\n", config.c_journal_pubmsgs);
		cprintf("%s\n", config.c_journal_dest);
		cprintf("%s\n", config.c_default_cal_zone);
		cprintf("%d\n", config.c_pftcpdict_port);
		cprintf("%d\n", config.c_managesieve_port);
	        cprintf("%d\n", config.c_auth_mode);
	        cprintf("%s\n", config.c_funambol_host);
	        cprintf("%d\n", config.c_funambol_port);
	        cprintf("%s\n", config.c_funambol_source);
	        cprintf("%s\n", config.c_funambol_auth);
		cprintf("%d\n", config.c_rbl_at_greeting);
		cprintf("%s\n", config.c_master_user);
		cprintf("%s\n", config.c_master_pass);
		cprintf("%s\n", config.c_pager_program);
		cprintf("%d\n", config.c_imap_keep_from);
		cprintf("%d\n", config.c_xmpp_c2s_port);
		cprintf("%d\n", config.c_xmpp_s2s_port);
		cprintf("%ld\n", config.c_pop3_fetch);
		cprintf("%ld\n", config.c_pop3_fastest);
		cprintf("%d\n", config.c_spam_flag_only);
		cprintf("%d\n", config.c_guest_logins);
		cprintf("%d\n", config.c_port_number);
		cprintf("%d\n", config.c_ctdluid);
		cprintf("%d\n", config.c_nntp_port);
		cprintf("%d\n", config.c_nntps_port);
		cprintf("000\n");
	}

	else if (!strcasecmp(cmd, "SET")) {
		unbuffer_output();
		cprintf("%d Send configuration...\n", SEND_LISTING);
		a = 0;
		while (client_getln(buf, sizeof buf) >= 0 && strcmp(buf, "000")) {
			switch (a) {
			case 0:
				configlen.c_nodename = safestrncpy(config.c_nodename, buf,
								   sizeof config.c_nodename);
				break;
			case 1:
				configlen.c_fqdn = safestrncpy(config.c_fqdn, buf,
							       sizeof config.c_fqdn);
				break;
			case 2:
				configlen.c_humannode = safestrncpy(config.c_humannode, buf,
								    sizeof config.c_humannode);
				break;
			case 3:
				configlen.c_phonenum = safestrncpy(config.c_phonenum, buf,
								   sizeof config.c_phonenum);
				break;
			case 4:
				config.c_creataide = atoi(buf);
				break;
			case 5:
				config.c_sleeping = atoi(buf);
				break;
			case 6:
				config.c_initax = atoi(buf);
				if (config.c_initax < 1)
					config.c_initax = 1;
				if (config.c_initax > 6)
					config.c_initax = 6;
				break;
			case 7:
				config.c_regiscall = atoi(buf);
				if (config.c_regiscall != 0)
					config.c_regiscall = 1;
				break;
			case 8:
				config.c_twitdetect = atoi(buf);
				if (config.c_twitdetect != 0)
					config.c_twitdetect = 1;
				break;
			case 9:
				configlen.c_twitroom = safestrncpy(config.c_twitroom, buf,
								   sizeof config.c_twitroom);
				break;
			case 10:
				configlen.c_moreprompt = safestrncpy(config.c_moreprompt, buf,
								     sizeof config.c_moreprompt);
				break;
			case 11:
				config.c_restrict = atoi(buf);
				if (config.c_restrict != 0)
					config.c_restrict = 1;
				break;
			case 12:
				configlen.c_site_location = safestrncpy(
					config.c_site_location, buf,
					sizeof config.c_site_location);
				break;
			case 13:
				configlen.c_sysadm = safestrncpy(config.c_sysadm, buf,
								 sizeof config.c_sysadm);
				break;
			case 14:
				config.c_maxsessions = atoi(buf);
				if (config.c_maxsessions < 0)
					config.c_maxsessions = 0;
				break;
			case 15:
				/* placeholder -- field no longer in use */
				break;
			case 16:
				config.c_userpurge = atoi(buf);
				break;
			case 17:
				config.c_roompurge = atoi(buf);
				break;
			case 18:
				configlen.c_logpages = safestrncpy(config.c_logpages, buf,
								   sizeof config.c_logpages);
				break;
			case 19:
				config.c_createax = atoi(buf);
				if (config.c_createax < 1)
					config.c_createax = 1;
				if (config.c_createax > 6)
					config.c_createax = 6;
				break;
			case 20:
				if (atoi(buf) >= 8192)
					config.c_maxmsglen = atoi(buf);
				break;
			case 21:
				if (atoi(buf) >= 2)
					config.c_min_workers = atoi(buf);
			case 22:
				if (atoi(buf) >= config.c_min_workers)
					config.c_max_workers = atoi(buf);
			case 23:
				config.c_pop3_port = atoi(buf);
				break;
			case 24:
				config.c_smtp_port = atoi(buf);
				break;
			case 25:
				config.c_rfc822_strict_from = atoi(buf);
				break;
			case 26:
				config.c_aide_zap = atoi(buf);
				if (config.c_aide_zap != 0)
					config.c_aide_zap = 1;
				break;
			case 27:
				config.c_imap_port = atoi(buf);
				break;
			case 28:
				config.c_net_freq = atol(buf);
				break;
			case 29:
				config.c_disable_newu = atoi(buf);
				if (config.c_disable_newu != 0)
					config.c_disable_newu = 1;
				break;
			case 30:
				/* niu */
				break;
			case 31:
				if ((config.c_purge_hour >= 0)
				    && (config.c_purge_hour <= 23)) {
					config.c_purge_hour = atoi(buf);
				}
				break;
#ifdef HAVE_LDAP
			case 32:
				configlen.c_ldap_host = safestrncpy(config.c_ldap_host, buf,
								    sizeof config.c_ldap_host);
				break;
			case 33:
				config.c_ldap_port = atoi(buf);
				break;
			case 34:
				configlen.c_ldap_base_dn = safestrncpy(config.c_ldap_base_dn, buf,
								       sizeof config.c_ldap_base_dn);
				break;
			case 35:
				configlen.c_ldap_bind_dn = safestrncpy(config.c_ldap_bind_dn, buf,
								       sizeof config.c_ldap_bind_dn);
				break;
			case 36:
				configlen.c_ldap_bind_pw = safestrncpy(config.c_ldap_bind_pw, buf,
								       sizeof config.c_ldap_bind_pw);
				break;
#endif
			case 37:
				configlen.c_ip_addr = safestrncpy(config.c_ip_addr, buf,
								  sizeof config.c_ip_addr);
			case 38:
				config.c_msa_port = atoi(buf);
				break;
			case 39:
				config.c_imaps_port = atoi(buf);
				break;
			case 40:
				config.c_pop3s_port = atoi(buf);
				break;
			case 41:
				config.c_smtps_port = atoi(buf);
				break;
			case 42:
				config.c_enable_fulltext = atoi(buf);
				break;
			case 43:
				config.c_auto_cull = atoi(buf);
				break;
			case 44:
				/* niu */
				break;
			case 45:
				config.c_allow_spoofing = atoi(buf);
				break;
			case 46:
				config.c_journal_email = atoi(buf);
				break;
			case 47:
				config.c_journal_pubmsgs = atoi(buf);
				break;
			case 48:
				configlen.c_journal_dest = safestrncpy(config.c_journal_dest, buf,
								       sizeof config.c_journal_dest);
			case 49:
				configlen.c_default_cal_zone = safestrncpy(
					config.c_default_cal_zone, buf,
					sizeof config.c_default_cal_zone);
				break;
			case 50:
				config.c_pftcpdict_port = atoi(buf);
				break;
			case 51:
				config.c_managesieve_port = atoi(buf);
				break;
			case 52:
				config.c_auth_mode = atoi(buf);
			case 53:
				configlen.c_funambol_host = safestrncpy(
					config.c_funambol_host, buf,
					sizeof config.c_funambol_host);
				break;
			case 54:
				config.c_funambol_port = atoi(buf);
				break;
			case 55:
				configlen.c_funambol_source = safestrncpy(
					config.c_funambol_source, buf, 
					sizeof config.c_funambol_source);
				break;
			case 56:
				configlen.c_funambol_auth = safestrncpy(
					config.c_funambol_auth, buf,
					sizeof config.c_funambol_auth);
				break;
			case 57:
				config.c_rbl_at_greeting = atoi(buf);
				break;
			case 58:
				configlen.c_master_user = safestrncpy(
					config.c_master_user,
					buf, sizeof config.c_master_user);
				break;
			case 59:
				configlen.c_master_pass = safestrncpy(
					config.c_master_pass, buf, sizeof config.c_master_pass);
				break;
			case 60:
				configlen.c_pager_program = safestrncpy(
					config.c_pager_program,	buf, sizeof config.c_pager_program);
				break;
			case 61:
				config.c_imap_keep_from = atoi(buf);
				break;
			case 62:
				config.c_xmpp_c2s_port = atoi(buf);
				break;
			case 63:
				config.c_xmpp_s2s_port = atoi(buf);
				break;
			case 64:
				config.c_pop3_fetch = atol(buf);
				break;
			case 65:
				config.c_pop3_fastest = atol(buf);
				break;
			case 66:
				config.c_spam_flag_only = atoi(buf);
				break;
			case 67:
				config.c_guest_logins = atoi(buf);
				break;
			case 68:
				config.c_port_number = atoi(buf);
				break;
			case 69:
				config.c_ctdluid = atoi(buf);
				break;
			case 70:
				config.c_nntp_port = atoi(buf);
				break;
			case 71:
				config.c_nntps_port = atoi(buf);
				break;
			}
			++a;
		}
		put_config();
		snprintf(buf, sizeof buf,
			"The global system configuration has been edited by %s.\n",
			 (CC->logged_in ? CC->curr_user : "******")
		);
		CtdlAideMessage(buf,"Citadel Configuration Manager Message");

		if (!IsEmptyStr(config.c_logpages))
			CtdlCreateRoom(config.c_logpages, 3, "", 0, 1, 1, VIEW_BBS);

		/* If full text indexing has been disabled, invalidate the
		 * index so it doesn't try to use it later.
		 */
		if (config.c_enable_fulltext == 0) {
			CitControl.fulltext_wordbreaker = 0;
			put_control();
		}
	}

	else if (!strcasecmp(cmd, "GETSYS")) {
		extract_token(confname, argbuf, 1, '|', sizeof confname);
		confptr = CtdlGetSysConfig(confname);
		if (confptr != NULL) {
			long len; 

			len = strlen(confptr);
			cprintf("%d %s\n", LISTING_FOLLOWS, confname);
			client_write(confptr, len);
			if ((len > 0) && (confptr[len - 1] != 10))
				client_write("\n", 1);
			cprintf("000\n");
			free(confptr);
		} else {
			cprintf("%d No such configuration.\n",
				ERROR + ILLEGAL_VALUE);
		}
	}

	else if (!strcasecmp(cmd, "PUTSYS")) {
		extract_token(confname, argbuf, 1, '|', sizeof confname);
		unbuffer_output();
		cprintf("%d %s\n", SEND_LISTING, confname);
		confptr = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
		CtdlPutSysConfig(confname, confptr);
		free(confptr);
	}

	else {
		cprintf("%d Illegal option(s) specified.\n",
			ERROR + ILLEGAL_VALUE);
	}
}
示例#8
0
int PurgeUsers(void) {
	struct PurgeList *pptr;
	int num_users_purged = 0;
	char *transcript = NULL;

	syslog(LOG_DEBUG, "PurgeUsers() called");
	users_not_purged = 0;

	switch(config.c_auth_mode) {
		case AUTHMODE_NATIVE:
			ForEachUser(do_user_purge, NULL);
			break;
		case AUTHMODE_HOST:
			ForEachUser(do_uid_user_purge, NULL);
			break;
		default:
			syslog(LOG_DEBUG, "User purge for auth mode %d is not implemented.",
				config.c_auth_mode);
			break;
	}

	transcript = malloc(SIZ);

	if (users_not_purged == 0) {
		strcpy(transcript, "The auto-purger was told to purge every user.  It is\n"
				"refusing to do this because it usually indicates a problem\n"
				"such as an inability to communicate with a name service.\n"
		);
		while (UserPurgeList != NULL) {
			pptr = UserPurgeList->next;
			free(UserPurgeList);
			UserPurgeList = pptr;
			++num_users_purged;
		}
	}

	else {
		strcpy(transcript, "The following users have been auto-purged:\n");
		while (UserPurgeList != NULL) {
			transcript=realloc(transcript, strlen(transcript)+SIZ);
			snprintf(&transcript[strlen(transcript)], SIZ, " %s\n",
				UserPurgeList->name);
			purge_user(UserPurgeList->name);
			pptr = UserPurgeList->next;
			free(UserPurgeList);
			UserPurgeList = pptr;
			++num_users_purged;
		}
	}

	if (num_users_purged > 0) CtdlAideMessage(transcript, "User Purge Message");
	free(transcript);

	if(users_corrupt_msg)
	{
		CtdlAideMessage(users_corrupt_msg, "User Corruption Message");
		free (users_corrupt_msg);
		users_corrupt_msg = NULL;
	}
	
	if(users_zero_msg)
	{
		CtdlAideMessage(users_zero_msg, "User Zero Message");
		free (users_zero_msg);
		users_zero_msg = NULL;
	}
		
	syslog(LOG_DEBUG, "Purged %d users.", num_users_purged);
	return(num_users_purged);
}
示例#9
0
/*
 * create a new room
 */
void cmd_cre8(char *args)
{
	int cre8_ok;
	char new_room_name[ROOMNAMELEN];
	int new_room_type;
	char new_room_pass[32];
	int new_room_floor;
	int new_room_view;
	char *notification_message = NULL;
	unsigned newflags;
	struct floor *fl;
	int avoid_access = 0;

	cre8_ok = extract_int(args, 0);
	extract_token(new_room_name, args, 1, '|', sizeof new_room_name);
	new_room_name[ROOMNAMELEN - 1] = 0;
	new_room_type = extract_int(args, 2);
	extract_token(new_room_pass, args, 3, '|', sizeof new_room_pass);
	avoid_access = extract_int(args, 5);
	new_room_view = extract_int(args, 6);
	new_room_pass[9] = 0;
	new_room_floor = 0;

	if ((IsEmptyStr(new_room_name)) && (cre8_ok == 1)) {
		cprintf("%d Invalid room name.\n", ERROR + ILLEGAL_VALUE);
		return;
	}

	if (!strcasecmp(new_room_name, MAILROOM)) {
		cprintf("%d '%s' already exists.\n",
			ERROR + ALREADY_EXISTS, new_room_name);
		return;
	}

	if (num_parms(args) >= 5) {
		fl = CtdlGetCachedFloor(extract_int(args, 4));
		if (fl == NULL) {
			cprintf("%d Invalid floor number.\n",
				ERROR + INVALID_FLOOR_OPERATION);
			return;
		}
		else if ((fl->f_flags & F_INUSE) == 0) {
			cprintf("%d Invalid floor number.\n",
				ERROR + INVALID_FLOOR_OPERATION);
			return;
		} else {
			new_room_floor = extract_int(args, 4);
		}
	}

	if (CtdlAccessCheck(ac_logged_in)) return;

	if (CC->user.axlevel < CtdlGetConfigInt("c_createax") && !CC->internal_pgm) {
		cprintf("%d You need higher access to create rooms.\n",
			ERROR + HIGHER_ACCESS_REQUIRED);
		return;
	}

	if ((IsEmptyStr(new_room_name)) && (cre8_ok == 0)) {
		cprintf("%d Ok to create rooms.\n", CIT_OK);
		return;
	}

	if ((new_room_type < 0) || (new_room_type > 5)) {
		cprintf("%d Invalid room type.\n", ERROR + ILLEGAL_VALUE);
		return;
	}

	if (new_room_type == 5) {
		if (CC->user.axlevel < AxAideU) {
			cprintf("%d Higher access required\n", 
				ERROR + HIGHER_ACCESS_REQUIRED);
			return;
		}
	}

	/* Check to make sure the requested room name doesn't already exist */
	newflags = CtdlCreateRoom(new_room_name,
				new_room_type, new_room_pass, new_room_floor,
				0, avoid_access, new_room_view);
	if (newflags == 0) {
		cprintf("%d '%s' already exists.\n",
			ERROR + ALREADY_EXISTS, new_room_name);
		return;
	}

	if (cre8_ok == 0) {
		cprintf("%d OK to create '%s'\n", CIT_OK, new_room_name);
		return;
	}

	/* If we reach this point, the room needs to be created. */

	newflags = CtdlCreateRoom(new_room_name,
			   new_room_type, new_room_pass, new_room_floor, 1, 0,
			   new_room_view);

	/* post a message in Aide> describing the new room */
	notification_message = malloc(1024);
	snprintf(notification_message, 1024,
		"A new room called \"%s\" has been created by %s%s%s%s%s%s\n",
		new_room_name,
		(CC->logged_in ? CC->curr_user : "******"),
		((newflags & QR_MAILBOX) ? " [personal]" : ""),
		((newflags & QR_PRIVATE) ? " [private]" : ""),
		((newflags & QR_GUESSNAME) ? " [hidden]" : ""),
		((newflags & QR_PASSWORDED) ? " Password: "******""),
		((newflags & QR_PASSWORDED) ? new_room_pass : "")
	);
	CtdlAideMessage(notification_message, "Room Creation Message");
	free(notification_message);

	cprintf("%d '%s' has been created.\n", CIT_OK, new_room_name);
}
示例#10
0
/*
 * set room parameters (admin or room admin command)
 */
void cmd_setr(char *args)
{
	char buf[256];
	int new_order = 0;
	int r;
	int new_floor;
	char new_name[ROOMNAMELEN];

	if (CtdlAccessCheck(ac_logged_in)) return;

	if (num_parms(args) >= 6) {
		new_floor = extract_int(args, 5);
	} else {
		new_floor = (-1);	/* don't change the floor */
	}

	/* When is a new name more than just a new name?  When the old name
	 * has a namespace prefix.
	 */
	if (CC->room.QRflags & QR_MAILBOX) {
		sprintf(new_name, "%010ld.", atol(CC->room.QRname) );
	} else {
		safestrncpy(new_name, "", sizeof new_name);
	}
	extract_token(&new_name[strlen(new_name)], args, 0, '|', (sizeof new_name - strlen(new_name)));

	r = CtdlRenameRoom(CC->room.QRname, new_name, new_floor);

	if (r == crr_room_not_found) {
		cprintf("%d Internal error - room not found?\n", ERROR + INTERNAL_ERROR);
	} else if (r == crr_already_exists) {
		cprintf("%d '%s' already exists.\n",
			ERROR + ALREADY_EXISTS, new_name);
	} else if (r == crr_noneditable) {
		cprintf("%d Cannot edit this room.\n", ERROR + NOT_HERE);
	} else if (r == crr_invalid_floor) {
		cprintf("%d Target floor does not exist.\n",
			ERROR + INVALID_FLOOR_OPERATION);
	} else if (r == crr_access_denied) {
		cprintf("%d You do not have permission to edit '%s'\n",
			ERROR + HIGHER_ACCESS_REQUIRED,
			CC->room.QRname);
	} else if (r != crr_ok) {
		cprintf("%d Error: CtdlRenameRoom() returned %d\n",
			ERROR + INTERNAL_ERROR, r);
	}

	if (r != crr_ok) {
		return;
	}

	CtdlGetRoom(&CC->room, new_name);

	/* Now we have to do a bunch of other stuff */

	if (num_parms(args) >= 7) {
		new_order = extract_int(args, 6);
		if (new_order < 1)
			new_order = 1;
		if (new_order > 127)
			new_order = 127;
	}

	CtdlGetRoomLock(&CC->room, CC->room.QRname);

	/* Directory room */
	extract_token(buf, args, 2, '|', sizeof buf);
	buf[15] = 0;
	safestrncpy(CC->room.QRdirname, buf,
		sizeof CC->room.QRdirname);

	/* Default view */
	if (num_parms(args) >= 8) {
		CC->room.QRdefaultview = extract_int(args, 7);
	}

	/* Second set of flags */
	if (num_parms(args) >= 9) {
		CC->room.QRflags2 = extract_int(args, 8);
	}

	/* Misc. flags */
	CC->room.QRflags = (extract_int(args, 3) | QR_INUSE);
	/* Clean up a client boo-boo: if the client set the room to
	 * guess-name or passworded, ensure that the private flag is
	 * also set.
	 */
	if ((CC->room.QRflags & QR_GUESSNAME)
	    || (CC->room.QRflags & QR_PASSWORDED))
		CC->room.QRflags |= QR_PRIVATE;

	/* Some changes can't apply to BASEROOM */
	if (!strncasecmp(CC->room.QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) {
		CC->room.QRorder = 0;
		CC->room.QRpasswd[0] = '\0';
		CC->room.QRflags &= ~(QR_PRIVATE & QR_PASSWORDED &
			QR_GUESSNAME & QR_PREFONLY & QR_MAILBOX);
		CC->room.QRflags |= QR_PERMANENT;
	} else {	
		/* March order (doesn't apply to AIDEROOM) */
		if (num_parms(args) >= 7)
			CC->room.QRorder = (char) new_order;
		/* Room password */
		extract_token(buf, args, 1, '|', sizeof buf);
		buf[10] = 0;
		safestrncpy(CC->room.QRpasswd, buf,
			    sizeof CC->room.QRpasswd);
		/* Kick everyone out if the client requested it
		 * (by changing the room's generation number)
		 */
		if (extract_int(args, 4)) {
			time(&CC->room.QRgen);
		}
	}
	/* Some changes can't apply to AIDEROOM */
	if (!strncasecmp(CC->room.QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)) {
		CC->room.QRorder = 0;
		CC->room.QRflags &= ~QR_MAILBOX;
		CC->room.QRflags |= QR_PERMANENT;
	}

	/* Write the room record back to disk */
	CtdlPutRoomLock(&CC->room);

	/* Create a room directory if necessary */
	if (CC->room.QRflags & QR_DIRECTORY) {
		snprintf(buf, sizeof buf,"%s/%s",
				 ctdl_file_dir,
				 CC->room.QRdirname);
		mkdir(buf, 0755);
	}
	snprintf(buf, sizeof buf, "The room \"%s\" has been edited by %s.\n",
		CC->room.QRname,
		(CC->logged_in ? CC->curr_user : "******")
	);
	CtdlAideMessage(buf, "Room modification Message");
	cprintf("%d Ok\n", CIT_OK);
}
示例#11
0
/*
 * RDIR command for room directory
 */
void cmd_rdir(char *cmdbuf)
{
	char buf[256];
	char comment[256];
	FILE *fd;
	struct stat statbuf;
	DIR *filedir = NULL;
	struct dirent *filedir_entry;
	int d_namelen;
	char buf2[SIZ];
	char mimebuf[64];
	long len;
	
	if (CtdlAccessCheck(ac_logged_in)) return;
	
	CtdlGetRoom(&CC->room, CC->room.QRname);
	CtdlGetUser(&CC->user, CC->curr_user);

	if ((CC->room.QRflags & QR_DIRECTORY) == 0) {
		cprintf("%d not here.\n", ERROR + NOT_HERE);
		return;
	}
	if (((CC->room.QRflags & QR_VISDIR) == 0)
	    && (CC->user.axlevel < AxAideU)
	    && (CC->user.usernum != CC->room.QRroomaide)) {
		cprintf("%d not here.\n", ERROR + HIGHER_ACCESS_REQUIRED);
		return;
	}

	snprintf(buf, sizeof buf, "%s/%s", ctdl_file_dir, CC->room.QRdirname);
	filedir = opendir (buf);
	
	if (filedir == NULL) {
		cprintf("%d not here.\n", ERROR + HIGHER_ACCESS_REQUIRED);
		return;
	}
	cprintf("%d %s|%s/%s\n", LISTING_FOLLOWS, CtdlGetConfigStr("c_fqdn"), ctdl_file_dir, CC->room.QRdirname);
	
	snprintf(buf, sizeof buf, "%s/%s/filedir", ctdl_file_dir, CC->room.QRdirname);
	fd = fopen(buf, "r");
	if (fd == NULL)
		fd = fopen("/dev/null", "r");
	while ((filedir_entry = readdir(filedir)))
	{
		if (strcasecmp(filedir_entry->d_name, "filedir") && filedir_entry->d_name[0] != '.')
		{
#ifdef _DIRENT_HAVE_D_NAMELEN
			d_namelen = filedir_entry->d_namlen;
#else
			d_namelen = strlen(filedir_entry->d_name);
#endif
			snprintf(buf, sizeof buf, "%s/%s/%s", ctdl_file_dir, CC->room.QRdirname, filedir_entry->d_name);
			stat(buf, &statbuf);	/* stat the file */
			if (!(statbuf.st_mode & S_IFREG))
			{
				snprintf(buf2, sizeof buf2,
					"\"%s\" appears in the file directory for room \"%s\" but is not a regular file.  Directories, named pipes, sockets, etc. are not usable in Citadel room directories.\n",
					buf, CC->room.QRname
				);
				CtdlAideMessage(buf2, "Unusable data found in room directory");
				continue;	/* not a useable file type so don't show it */
			}
			safestrncpy(comment, "", sizeof comment);
			fseek(fd, 0L, 0);	/* rewind descriptions file */
			/* Get the description from the descriptions file */
			while ((fgets(buf, sizeof buf, fd) != NULL) && (IsEmptyStr(comment))) 
			{
				buf[strlen(buf) - 1] = 0;
				if ((!strncasecmp(buf, filedir_entry->d_name, d_namelen)) && (buf[d_namelen] == ' '))
					safestrncpy(comment, &buf[d_namelen + 1], sizeof comment);
			}
			len = extract_token (mimebuf, comment, 0,' ', 64);
			if ((len <0) || strchr(mimebuf, '/') == NULL)
			{
				snprintf (mimebuf, 64, "application/octetstream");
				len = 0;
			}
			cprintf("%s|%ld|%s|%s\n", 
				filedir_entry->d_name, 
				(long)statbuf.st_size, 
				mimebuf, 
				&comment[len]);
		}
	}
	fclose(fd);
	closedir(filedir);
	
	cprintf("000\n");
}
示例#12
0
/*
 * smtp_do_bounce() is caled by smtp_do_procmsg() to scan a set of delivery
 * instructions for "5" codes (permanent fatal errors) and produce/deliver
 * a "bounce" message (delivery status notification).
 */
void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay)
{
	static int seq = 0;
	
	struct CtdlMessage *bmsg = NULL;
	StrBuf *boundary;
	StrBuf *Msg = NULL;
	StrBuf *BounceMB;
	recptypes *valid;
	time_t now;

	HashPos *It;
	void *vQE;
	long len;
	const char *Key;

	int first_attempt = 0;
	int successful_bounce = 0;
	int num_bounces = 0;
	int give_up = 0;

	SMTPCM_syslog(LOG_DEBUG, "smtp_do_bounce() called\n");

	if (MyQItem->SendBounceMail == 0)
		return;

	now = time (NULL); //ev_time();

	if ( (now - MyQItem->Submitted) > SMTP_GIVE_UP ) {
		give_up = 1;
	}

	if (MyQItem->Retry == SMTP_RETRY_INTERVAL) {
		first_attempt = 1;
	}

	/*
	 * Now go through the instructions checking for stuff.
	 */
	Msg = NewStrBufPlain(NULL, 1024);
	It = GetNewHashPos(MyQItem->MailQEntries, 0);
	while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE))
	{
		MailQEntry *ThisItem = vQE;
		if ((ThisItem->Active && (ThisItem->Status == 5)) || /* failed now? */
		    ((give_up == 1) && (ThisItem->Status != 2)) ||
		    ((first_attempt == 1) && (ThisItem->Status != 2)))
			/* giving up after failed attempts... */
		{
			++num_bounces;

			StrBufAppendBufPlain(Msg, HKEY(" "), 0);
			StrBufAppendBuf(Msg, ThisItem->Recipient, 0);
			StrBufAppendBufPlain(Msg, HKEY(": "), 0);
			if (ThisItem->AllStatusMessages != NULL)
				StrBufAppendBuf(Msg, ThisItem->AllStatusMessages, 0);
			else
				StrBufAppendBuf(Msg, ThisItem->StatusMessage, 0);
			StrBufAppendBufPlain(Msg, HKEY("\r\n"), 0);
		}
	}
	DeleteHashPos(&It);

	/* Deliver the bounce if there's anything worth mentioning */
	SMTPC_syslog(LOG_DEBUG, "num_bounces = %d\n", num_bounces);

	if (num_bounces == 0) {
		FreeStrBuf(&Msg);
		return;
	}

	if ((StrLength(MyQItem->SenderRoom) == 0) && MyQItem->HaveRelay) {
		const char *RelayUrlStr = "[not found]";
		/* one message that relaying is broken is enough; no extra room error message. */
		StrBuf *RelayDetails = NewStrBuf();

		if (Relay != NULL)
			RelayUrlStr = ChrPtr(Relay->URL);

		StrBufPrintf(RelayDetails,
			     "Relaying via %s failed permanently. \n Reason:\n%s\n Revalidate your relay configuration.",
			     RelayUrlStr,
			     ChrPtr(Msg));
                CtdlAideMessage(ChrPtr(RelayDetails), "Relaying Failed");
		FreeStrBuf(&RelayDetails);
	}

	boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_"));
	StrBufAppendPrintf(boundary,
			   "%s_%04x%04x",
			   CtdlGetConfigStr("c_fqdn"),
			   getpid(),
			   ++seq);

	/* Start building our bounce message; go shopping for memory first. */
	BounceMB = NewStrBufPlain(
		NULL,
		1024 + /* mime stuff.... */
		StrLength(Msg) +  /* the bounce information... */
		StrLength(OMsgTxt)); /* the original message */
	if (BounceMB == NULL) {
		FreeStrBuf(&boundary);
		SMTPCM_syslog(LOG_ERR, "Failed to alloc() bounce message.\n");

		return;
	}

	bmsg = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage));
	if (bmsg == NULL) {
		FreeStrBuf(&boundary);
		FreeStrBuf(&BounceMB);
		SMTPCM_syslog(LOG_ERR, "Failed to alloc() bounce message.\n");

		return;
	}
	memset(bmsg, 0, sizeof(struct CtdlMessage));


	StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("X-Mailer: " CITADEL "\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\r\nThis is a multipart message in MIME format.\r\n\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("Content-type: text/plain\r\n\r\n"), 0);

	if (give_up)
		StrBufAppendBufPlain(
			BounceMB,
			HKEY(
				"A message you sent could not be delivered "
				"to some or all of its recipients\n"
				"due to prolonged unavailability "
				"of its destination(s).\n"
				"Giving up on the following addresses:\n\n"
				), 0);
	else
		StrBufAppendBufPlain(
			BounceMB,
			HKEY(
				"A message you sent could not be delivered "
				"to some or all of its recipients.\n"
				"The following addresses "
				"were undeliverable:\n\n"
				), 0);

	StrBufAppendBuf(BounceMB, Msg, 0);
	FreeStrBuf(&Msg);

	if (StrLength(MyQItem->SenderRoom) > 0)
	{
		StrBufAppendBufPlain(
			BounceMB,
			HKEY("The message was originaly posted in: "), 0);
		StrBufAppendBuf(BounceMB, MyQItem->SenderRoom, 0);
		StrBufAppendBufPlain(
			BounceMB,
			HKEY("\n"), 0);
	}

	/* Attach the original message */
	StrBufAppendBufPlain(BounceMB, HKEY("\r\n--"), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
	StrBufAppendBufPlain(BounceMB,
			     HKEY("Content-type: message/rfc822\r\n"), 0);
	StrBufAppendBufPlain(BounceMB,
			     HKEY("Content-Transfer-Encoding: 7bit\r\n"), 0);
	StrBufAppendBufPlain(BounceMB,
			     HKEY("Content-Disposition: inline\r\n"), 0);
	StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
	StrBufAppendBuf(BounceMB, OMsgTxt, 0);

	/* Close the multipart MIME scope */
	StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
	StrBufAppendBuf(BounceMB, boundary, 0);
	StrBufAppendBufPlain(BounceMB, HKEY("--\r\n"), 0);

	bmsg->cm_magic = CTDLMESSAGE_MAGIC;
	bmsg->cm_anon_type = MES_NORMAL;
	bmsg->cm_format_type = FMT_RFC822;

	CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM));
	CM_SetField(bmsg, eAuthor, HKEY("Citadel"));
	CM_SetField(bmsg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename")));
	CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)"));
	CM_SetAsFieldSB(bmsg, eMesageText, &BounceMB);

	/* First try the user who sent the message */
	if (StrLength(MyQItem->BounceTo) == 0) {
		SMTPCM_syslog(LOG_ERR, "No bounce address specified\n");
	}
	else {
		SMTPC_syslog(LOG_DEBUG, "bounce to user? <%s>\n",
		       ChrPtr(MyQItem->BounceTo));
	}

	/* Can we deliver the bounce to the original sender? */
	valid = validate_recipients(ChrPtr(MyQItem->BounceTo), NULL, 0);
	if ((valid != NULL) && (valid->num_error == 0)) {
		CtdlSubmitMsg(bmsg, valid, "", QP_EADDR);
		successful_bounce = 1;
	}

	/* If not, post it in the Aide> room */
	if (successful_bounce == 0) {
		CtdlSubmitMsg(bmsg, NULL, CtdlGetConfigStr("c_aideroom"), QP_EADDR);
	}

	/* Free up the memory we used */
	free_recipients(valid);
	FreeStrBuf(&boundary);
	CM_Free(bmsg);
	SMTPCM_syslog(LOG_DEBUG, "Done processing bounces\n");
}