/// <summary> /// Stores IMAP message flags (\seen,\draft, ...). /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder which message flags to store. For example: Inbox,Public Folders/Documnets .</param> /// <param name="message">Fix ME: ???</param> /// <param name="msgFlags">Message flags to store.</param> public void StoreMessageFlags(string accessingUser,string folderOwnerUser,string folder,LumiSoft.Net.IMAP.Server.IMAP_Message message,IMAP_MessageFlags msgFlags) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) Remove all message flags which permissions user doesn't have. *) Store message. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(message); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // Remove all message flags which permissions user doesn't have. if(accessingUser != "system"){ IMAP_ACL_Flags userACL = GetUserACL(folderOwnerUser,folder,accessingUser); if((userACL & IMAP_ACL_Flags.s) == 0){ msgFlags &= ~IMAP_MessageFlags.Seen; } else if((userACL & IMAP_ACL_Flags.d) == 0){ msgFlags &= ~IMAP_MessageFlags.Deleted; } else if((userACL & IMAP_ACL_Flags.s) == 0){ msgFlags &= (~IMAP_MessageFlags.Answered | ~IMAP_MessageFlags.Draft | ~IMAP_MessageFlags.Flagged); } } //--- Store message flags using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreMessageFlags")){ sqlCmd.AddParameter("_userName" ,NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,message.ID); sqlCmd.AddParameter("_messageFlags" ,NpgsqlDbType.Integer,(int)message.Flags); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Creates new IMAP folder. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what contains message to copy. For example: Inbox,Public Folders/Documnets .</param> public void CreateFolder(string accessingUser,string folderOwnerUser,string folder) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder doesn't exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'c' permission. There is builtin user system, skip ACL for it. *) Create folder. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder doesn't exists. Throw Exception if don't. if(FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' already exist !"); } // See if user has sufficient permissions. User requires 'c' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.c) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Create folder using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_CreateFolder")){ sqlCmd.AddParameter("_folderID",NpgsqlDbType.Varchar,Guid.NewGuid().ToString()); sqlCmd.AddParameter("_userName",NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Deletes specified filter. /// </summary> /// <param name="filterID">FilterID of the filter which to delete.</param> public void DeleteFilter(string filterID) { using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_DeleteFilter")){ sqlCmd.AddParameter("_filterID" ,NpgsqlDbType.Varchar,filterID); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// AAdds new remote pop3 server to user. /// </summary> /// <param name="serverID">Server ID. Suggested value is Guid.NewGuid() .</param> /// <param name="userName">User name. Use <see cref="IMailServerApi.GetUsers">GetUsers()</see> to get valid values.</param> /// <param name="description">Remote server description.</param> /// <param name="remoteServer">Remote server name.</param> /// <param name="remotePort">Remote server port.</param> /// <param name="remoteUser">Remote server user name.</param> /// <param name="remotePassword">Remote server password.</param> /// <param name="useSSL">Specifies if SSL must be used to connect to remote server.</param> /// <param name="enabled">Specifies if remote server is enabled.</param> /// <remarks>Throws exception if specified user remote server already exists.</remarks> public void AddUserRemoteServer(string serverID,string userName,string description,string remoteServer,int remotePort,string remoteUser,string remotePassword,bool useSSL,bool enabled) { if(serverID.Length == 0){ throw new Exception("You must specify serverID"); } if(userName.Length == 0){ throw new Exception("You must specify userName"); } using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_AddUserRemoteServer")){ sqlCmd.AddParameter("_serverID" ,NpgsqlDbType.Varchar,serverID); sqlCmd.AddParameter("_userName" ,NpgsqlDbType.Varchar,userName); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_remoteServer" ,NpgsqlDbType.Varchar,remoteServer); sqlCmd.AddParameter("_remotePort" ,NpgsqlDbType.Integer,remotePort); sqlCmd.AddParameter("_remoteUserName" ,NpgsqlDbType.Varchar,remoteUser); sqlCmd.AddParameter("_remotePassword" ,NpgsqlDbType.Varchar,remotePassword); sqlCmd.AddParameter("_useSSL" ,NpgsqlDbType.Boolean,useSSL); sqlCmd.AddParameter("_enabled" ,NpgsqlDbType.Boolean,enabled); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Authenticates user. /// </summary> /// <param name="userName">User name.</param> /// <param name="passwData">Password data.</param> /// <param name="authData">Authentication specific data(as tag).</param> /// <param name="authType">Authentication type.</param> /// <returns></returns> public DataSet AuthUser(string userName,string passwData,string authData,AuthType authType) { DataSet retVal = new DataSet(); DataTable dt = retVal.Tables.Add("Result"); dt.Columns.Add("Result"); dt.Columns.Add("ReturnData"); DataRow drx = dt.NewRow(); drx["Result"] = "false"; drx["ReturnData"] = ""; dt.Rows.Add(drx); using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetUserProperties")){ sqlCmd.AddParameter("_userName",NpgsqlDbType.Varchar,userName); DataSet ds = sqlCmd.Execute(); ds.Tables[0].TableName = "Users"; if(ds.Tables["Users"].Rows.Count > 0){ string password = ds.Tables["Users"].Rows[0]["PASSWORD"].ToString().ToLower(); switch(authType) { case AuthType.APOP: if(AuthHelper.Apop(password,authData) == passwData){ drx["Result"] = "true"; return retVal; } break; case AuthType.CRAM_MD5: if(AuthHelper.Cram_Md5(password,authData) == passwData){ drx["Result"] = "true"; return retVal; } break; case AuthType.DIGEST_MD5: string realm = ""; string nonce = ""; string cnonce = ""; string digest_uri = ""; foreach(string clntRespParam in authData.Split(',')){ if(clntRespParam.StartsWith("realm=")){ realm = clntRespParam.Split(new char[]{'='},2)[1].Replace("\"",""); } else if(clntRespParam.StartsWith("nonce=")){ nonce = clntRespParam.Split(new char[]{'='},2)[1].Replace("\"",""); } else if(clntRespParam.StartsWith("cnonce=")){ cnonce = clntRespParam.Split(new char[]{'='},2)[1].Replace("\"",""); } else if(clntRespParam.StartsWith("digest-uri=")){ digest_uri = clntRespParam.Split(new char[]{'='},2)[1].Replace("\"",""); } } if(passwData == AuthHelper.Digest_Md5(true,realm,userName,password,nonce,cnonce,digest_uri)){ string returnData = AuthHelper.Digest_Md5(false,realm,userName,password,nonce,cnonce,digest_uri); drx["Result"] = "true"; drx["ReturnData"] = returnData; return retVal; } break; case AuthType.Plain: if(password == passwData.ToLower()){ drx["Result"] = "true"; return retVal; } break; } } } return retVal; }
/// <summary> /// Adds new user to specified domain. /// </summary> /// <param name="userID">User ID. Suggested value is Guid.NewGuid() .</param> /// <param name="userName">User login name.</param> /// <param name="fullName">User full name.</param> /// <param name="password">User login password.</param> /// <param name="description">User description.</param> /// <param name="domainName">Domain where to add user. Use <see cref="IMailServerApi.GetDomains">GetDomains()</see> to get valid values.</param> /// <param name="mailboxSize">Maximum mailbox size.</param> /// <param name="enabled">Sepcifies if user is enabled.</param> /// <param name="permissions">Specifies user permissions.</param> /// <remarks>Throws exception if specified user already exists.</remarks> public void AddUser(string userID,string userName,string fullName,string password,string description,string domainName,int mailboxSize,bool enabled,UserPermissions_enum permissions) { if(userID.Length == 0){ throw new Exception("You must specify userID"); } if(userName.Length == 0){ throw new Exception("You must specify userName"); } using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_AddUser")){ sqlCmd.AddParameter("_userID" ,NpgsqlDbType.Varchar,userID); sqlCmd.AddParameter("_fullName" ,NpgsqlDbType.Varchar,fullName); sqlCmd.AddParameter("_userName" ,NpgsqlDbType.Varchar,userName); sqlCmd.AddParameter("_password" ,NpgsqlDbType.Varchar,password); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_domainName" ,NpgsqlDbType.Varchar,domainName); sqlCmd.AddParameter("_mailboxSize" ,NpgsqlDbType.Integer,mailboxSize); sqlCmd.AddParameter("_enabled" ,NpgsqlDbType.Boolean,enabled); sqlCmd.AddParameter("_permissions" ,NpgsqlDbType.Integer,permissions); DataSet ds = sqlCmd.Execute(); ds.Tables[0].TableName = "Users"; } }
/// <summary> /// Adds new user message rule. /// </summary> /// <param name="userID">User who owns specified rule.</param> /// <param name="ruleID">Rule ID. Guid.NewID().ToString() is suggested.</param> /// <param name="cost">Cost specifies in what order rules are processed. Costs with lower values are processed first.</param> /// <param name="enabled">Specifies if rule is enabled.</param> /// <param name="checkNextRule">Specifies when next rule is checked.</param> /// <param name="description">Rule description.</param> /// <param name="matchExpression">Rule match expression.</param> public void AddUserMessageRule(string userID,string ruleID,long cost,bool enabled,GlobalMessageRule_CheckNextRule_enum checkNextRule,string description,string matchExpression) { if(userID == null || userID == ""){ throw new Exception("Invalid userID value, userID can't be '' or null !"); } if(ruleID == null || ruleID == ""){ throw new Exception("Invalid ruleID value, ruleID can't be '' or null !"); } using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_AddUserMessageRule")){ sqlCmd.AddParameter("_userID" ,NpgsqlDbType.Varchar,userID); sqlCmd.AddParameter("_ruleID" ,NpgsqlDbType.Varchar,ruleID); sqlCmd.AddParameter("_cost" ,NpgsqlDbType.Bigint ,cost); sqlCmd.AddParameter("_enabled" ,NpgsqlDbType.Boolean ,enabled); sqlCmd.AddParameter("_checkNextRule" ,NpgsqlDbType.Integer ,checkNextRule); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_matchExpression" ,NpgsqlDbType.Bytea ,System.Text.Encoding.Default.GetBytes(matchExpression)); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Updates specified mailing list. /// </summary> /// <param name="mailingListID">Mailing list ID.</param> /// <param name="mailingListName">Mailing list name name. Use <see cref="IMailServerApi.GetMailingLists">GetMailingLists()</see> to get valid values.</param> /// <param name="description">Mailing list description.</param> /// <param name="domainName">Domain name. Use <see cref="IMailServerApi.GetDomains">>GetUsers()</see> to get valid values.</param> /// <param name="enabled">Specifies if mailing list is enabled.</param> public void UpdateMailingList(string mailingListID,string mailingListName,string description,string domainName,bool enabled) { if(mailingListName.Length == 0){ throw new Exception("You must specify mailingListName"); } using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_UpdateMailingList")){ sqlCmd.AddParameter("_mailingListID" ,NpgsqlDbType.Varchar,mailingListID); sqlCmd.AddParameter("_mailingListName" ,NpgsqlDbType.Varchar,mailingListName); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_domainName" ,NpgsqlDbType.Varchar,domainName); sqlCmd.AddParameter("_enabled" ,NpgsqlDbType.Boolean,enabled); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Updates recycle bin settings. /// </summary> /// <param name="deleteToRecycleBin">Specifies if deleted messages are store to recycle bin.</param> /// <param name="deleteMessagesAfter">Specifies how old messages will be deleted.</param> public void UpdateRecycleBinSettings(bool deleteToRecycleBin,int deleteMessagesAfter) { using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_UpdateRecycleBinSettings")){ sqlCmd.AddParameter("_deleteToRecycleBin" ,NpgsqlDbType.Boolean,deleteToRecycleBin); sqlCmd.AddParameter("_deleteMessagesAfter",NpgsqlDbType.Integer,deleteMessagesAfter); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Updates specified filter. /// </summary> /// <param name="filterID">FilterID which to update.</param> /// <param name="description">Filter description</param> /// <param name="type">Filter type. Eg. ISmtpMessageFilter.</param> /// <param name="assembly">Assembly with full location. Eg. C:\MailServer\Filters\filter.dll .</param> /// <param name="className">Filter full class name, wih namespace. Eg. LumiSoft.MailServer.Fileters.Filter1 .</param> /// <param name="cost">Filters are sorted by cost and proccessed with cost value. Smallest cost is proccessed first.</param> /// <param name="enabled">Specifies if filter is enabled.</param> /// <returns></returns> public void UpdateFilter(string filterID,string description,string type,string assembly,string className,long cost,bool enabled) { using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_UpdateFilter")){ sqlCmd.AddParameter("_filterID" ,NpgsqlDbType.Varchar,filterID); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_type" ,NpgsqlDbType.Varchar,type); sqlCmd.AddParameter("_assembly" ,NpgsqlDbType.Varchar,assembly); sqlCmd.AddParameter("_className" ,NpgsqlDbType.Varchar,className); sqlCmd.AddParameter("_cost" ,NpgsqlDbType.Bigint ,cost); sqlCmd.AddParameter("_enabled" ,NpgsqlDbType.Boolean,enabled); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Updates user group info. /// </summary> /// <param name="groupID">Group ID.</param> /// <param name="groupName">Group name.</param> /// <param name="description">Group description.</param> /// <param name="enabled">Specifies if group is enabled.</param> public void UpdateGroup(string groupID,string groupName,string description,bool enabled) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that group with specified ID does exist. Throw Exception if doesn't. *) If group name is changed, ensure that new group name won't conflict any other group or user name. Throw Exception if does. *) Udpate group. */ //--- Validate values --------------------// if(groupID == null || groupID == ""){ throw new Exception("Invalid groupID value, groupID can't be '' or null !"); } ArgsValidator.ValidateUserName(groupName); ArgsValidator.ValidateNotNull(description); //----------------------------------------// /* We handle these is SQL, sql throws Excption *) Ensure that group with specified ID does exist. Throw Exception if doesn't. *) If group name is changed, ensure that new group name won't conflict any other group or user name. Throw Exception if does. */ // Update group using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_UpdateGroup")){ sqlCmd.AddParameter("_groupID" ,NpgsqlDbType.Varchar,groupID); sqlCmd.AddParameter("_groupName" ,NpgsqlDbType.Varchar,groupName); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_enabled" ,NpgsqlDbType.Boolean,enabled); DataSet ds = sqlCmd.Execute(); ds.Tables[0].TableName = "Groups"; } }
/// <summary> /// Updates specified domain data. /// </summary> /// <param name="domainID">Domain ID which to update.</param> /// <param name="domainName">Domain name.</param> /// <param name="description">Domain description.</param> public void UpdateDomain(string domainID,string domainName,string description) { if(domainID.Length == 0){ throw new Exception("You must specify domainID"); } ArgsValidator.ValidateDomainName(domainName); using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_UpdateDomain")){ sqlCmd.AddParameter("_domainID" ,NpgsqlDbType.Varchar,domainID); sqlCmd.AddParameter("_domainName" ,NpgsqlDbType.Varchar,domainName); sqlCmd.AddParameter("_description",NpgsqlDbType.Varchar,description); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// UnSubscribes IMAP folder. /// </summary> /// <param name="userName"></param> /// <param name="folder"></param> public void UnSubscribeFolder(string userName,string folder) { using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_UnSubscribeFolder")){ sqlCmd.AddParameter("_userName",NpgsqlDbType.Varchar,userName); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Add new email address to specified mailing list. /// </summary> /// <param name="addressID">Address ID. Suggested value is Guid.NewGuid() .</param> /// <param name="mailingListName">Mailing list name name. Use <see cref="IMailServerApi.GetMailingLists">GetMailingLists()</see> to get valid values.</param> /// <param name="address">Mailing list member address.</param> /// <remarks>Throws exception if specified mailing list member already exists.</remarks> public void AddMailingListAddress(string addressID,string mailingListName,string address) { if(addressID.Length == 0){ throw new Exception("You must specify addressID"); } if(mailingListName.Length == 0){ throw new Exception("You must specify mailingListName"); } if(address.Length == 0){ throw new Exception("You must specify address"); } using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_AddMailingListAddress")){ sqlCmd.AddParameter("_addressID" ,NpgsqlDbType.Varchar,addressID); sqlCmd.AddParameter("_mailingListName" ,NpgsqlDbType.Varchar,mailingListName); sqlCmd.AddParameter("_address" ,NpgsqlDbType.Varchar,address); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Adds new IP security entry. /// </summary> /// <param name="id">IP security entry ID.</param> /// <param name="enabled">Specifies if IP security entry is enabled.</param> /// <param name="description">IP security entry description text.</param> /// <param name="service">Specifies service for what security entry applies.</param> /// <param name="action">Specifies what action done if IP matches to security entry range.</param> /// <param name="startIP">Range start IP.</param> /// <param name="endIP">Range end IP.</param> public void AddSecurityEntry(string id,bool enabled,string description,Service_enum service,IPSecurityAction_enum action,IPAddress startIP,IPAddress endIP) { if(id.Length == 0){ throw new Exception("You must specify securityID"); } using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_AddSecurityEntry")){ sqlCmd.AddParameter("_id" ,NpgsqlDbType.Varchar,id); sqlCmd.AddParameter("_enabled" ,NpgsqlDbType.Boolean,enabled); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_service" ,NpgsqlDbType.Integer,(int)service); sqlCmd.AddParameter("_action" ,NpgsqlDbType.Integer,(int)action); sqlCmd.AddParameter("_startIP" ,NpgsqlDbType.Varchar,startIP.ToString()); sqlCmd.AddParameter("_endIP" ,NpgsqlDbType.Varchar,endIP.ToString()); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Updates IP security entry. /// </summary> /// <param name="id">IP security entry ID.</param> /// <param name="enabled">Specifies if IP security entry is enabled.</param> /// <param name="description">IP security entry description text.</param> /// <param name="service">Specifies service for what security entry applies.</param> /// <param name="action">Specifies what action done if IP matches to security entry range.</param> /// <param name="startIP">Range start IP.</param> /// <param name="endIP">Range end IP.</param> public void UpdateSecurityEntry(string id,bool enabled,string description,Service_enum service,IPSecurityAction_enum action,IPAddress startIP,IPAddress endIP) { using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_UpdateSecurityEntry")){ sqlCmd.AddParameter("_id" ,NpgsqlDbType.Varchar,id); sqlCmd.AddParameter("_enabled" ,NpgsqlDbType.Boolean,enabled); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_service" ,NpgsqlDbType.Integer,(int)service); sqlCmd.AddParameter("_action" ,NpgsqlDbType.Integer,(int)action); sqlCmd.AddParameter("_startIP" ,NpgsqlDbType.Varchar,startIP.ToString()); sqlCmd.AddParameter("_endIP" ,NpgsqlDbType.Varchar,endIP.ToString()); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Add shared folder root. /// </summary> /// <param name="rootID">Root folder ID. Guid.NewID().ToString() is suggested.</param> /// <param name="enabled">Specifies if root folder is enabled.</param> /// <param name="folder">Folder name which will be visible to public.</param> /// <param name="description">Description text.</param> /// <param name="rootType">Specifies what type root folder is.</param> /// <param name="boundedUser">User which to bound root folder.</param> /// <param name="boundedFolder">Folder which to bound to public folder.</param> public void AddSharedFolderRoot(string rootID,bool enabled,string folder,string description,SharedFolderRootType_enum rootType,string boundedUser,string boundedFolder) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that root ID doesn't exists. *) Ensure that root doesn't exists. *) Add root folder. */ if(rootID == null || rootID == ""){ throw new Exception("Invalid rootID value, rootID can't be '' or null !"); } //--- Validate values -------------------------------------// ArgsValidator.ValidateNotNull(rootID); ArgsValidator.ValidateSharedFolderRoot(folder); ArgsValidator.ValidateNotNull(description); if(rootType == SharedFolderRootType_enum.BoundedRootFolder){ ArgsValidator.ValidateUserName(boundedUser); ArgsValidator.ValidateFolder(boundedFolder); } //---------------------------------------------------------// /* We handle these is SQL, sql returns these errors in ErrorText *) Ensure that root ID doesn't exists. *) Ensure that root doesn't exists. */ // Insert group using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_AddSharedFolderRoot")){ sqlCmd.AddParameter("_rootID" ,NpgsqlDbType.Varchar,rootID); sqlCmd.AddParameter("_enabled" ,NpgsqlDbType.Boolean,enabled); sqlCmd.AddParameter("-folder" ,NpgsqlDbType.Varchar,folder); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_rootType" ,NpgsqlDbType.Integer,rootType); sqlCmd.AddParameter("_boundedUser" ,NpgsqlDbType.Varchar,boundedUser); sqlCmd.AddParameter("_boundedFolder" ,NpgsqlDbType.Varchar,boundedFolder); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Updates server settings. /// </summary> public void UpdateSettings(DataRow settings) { /* DataRow row = GetSettings(); foreach(DataColumn dc in row.Table.Columns){ row[dc.ColumnName] = settings[dc.ColumnName]; }*/ using(MemoryStream strm = new MemoryStream()){ settings.Table.DataSet.WriteXml(strm); using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_UpdateSettings")){ sqlCmd.AddParameter("_settings" ,NpgsqlDbType.Bytea,strm.ToArray()); DataSet ds = sqlCmd.Execute(); } } }
/// <summary> /// Add new email address to user. /// </summary> /// <param name="userName">User name. Use <see cref="IMailServerApi.GetUsers">>GetUsers()</see> to get valid values.</param> /// <param name="emailAddress">Email address to add.</param> /// <remarks>Throws exception if specified user email address exists.</remarks> public void AddUserAddress(string userName,string emailAddress) { if(userName.Length == 0){ throw new Exception("You must specify userName"); } if(emailAddress.Length == 0){ throw new Exception("You must specify address"); } if(emailAddress.IndexOf('@') == -1){ throw new Exception("Invalid email address, @ is missing !"); } string[] localPart_domain = emailAddress.Split('@'); using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_AddEmailAddress")){ sqlCmd.AddParameter("_localPart" ,NpgsqlDbType.Varchar,localPart_domain[0]); sqlCmd.AddParameter("_domainName",NpgsqlDbType.Varchar,localPart_domain[1]); sqlCmd.AddParameter("_OwnerID" ,NpgsqlDbType.Varchar,GetUserID(userName)); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Adds new route. /// </summary> /// <param name="routeID">Route ID.</param> /// <param name="cost">Cost specifies in what order roues are processed. Costs with lower values are processed first.</param> /// <param name="enabled">Specifies if route is enabled.</param> /// <param name="description">Route description text.</param> /// <param name="pattern">Match pattern. For example: *,*@domain.com,*[email protected].</param> /// <param name="action">Specifies route action.</param> /// <param name="actionData">Route action data.</param> public void AddRoute(string routeID,long cost,bool enabled,string description,string pattern,RouteAction_enum action,byte[] actionData) { if(routeID.Length == 0){ throw new Exception("You must specify routeID"); } if(pattern.Length == 0){ throw new Exception("You must specify pattern"); } using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_AddRoute")){ sqlCmd.AddParameter("_routeID" ,NpgsqlDbType.Varchar,routeID); sqlCmd.AddParameter("_cost" ,NpgsqlDbType.Bigint ,cost); sqlCmd.AddParameter("_enabled" ,NpgsqlDbType.Boolean,enabled); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_pattern" ,NpgsqlDbType.Varchar,pattern); sqlCmd.AddParameter("_action" ,NpgsqlDbType.Integer,action); sqlCmd.AddParameter("_actionData" ,NpgsqlDbType.Bytea ,actionData); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Adds action to specified user message rule. /// </summary> /// <param name="userID">User who owns specified rule.</param> /// <param name="ruleID">Rule ID to which to add this action.</param> /// <param name="actionID">Action ID. Guid.NewID().ToString() is suggested.</param> /// <param name="description">Action description.</param> /// <param name="actionType">Action type.</param> /// <param name="actionData">Action data. Data structure depends on action type.</param> public void AddUserMessageRuleAction(string userID,string ruleID,string actionID,string description,GlobalMessageRuleAction_enum actionType,byte[] actionData) { if(userID == null || userID == ""){ throw new Exception("Invalid userID value, userID can't be '' or null !"); } if(ruleID == null || ruleID == ""){ throw new Exception("Invalid ruleID value, ruleID can't be '' or null !"); } if(actionID == null || actionID == ""){ throw new Exception("Invalid actionID value, actionID can't be '' or null !"); } using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_AddUserMessageRuleAction")){ sqlCmd.AddParameter("_userID" ,NpgsqlDbType.Varchar,userID); sqlCmd.AddParameter("_ruleID" ,NpgsqlDbType.Varchar,ruleID); sqlCmd.AddParameter("_actionID" ,NpgsqlDbType.Varchar,actionID); sqlCmd.AddParameter("_description" ,NpgsqlDbType.Varchar,description); sqlCmd.AddParameter("_actionType" ,NpgsqlDbType.Integer,(int)actionType); sqlCmd.AddParameter("_actionData" ,NpgsqlDbType.Bytea ,actionData); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Updates user last login time. /// </summary> /// <param name="userName">User name who's last login time to update.</param> public void UpdateUserLastLoginTime(string userName) { using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_UpdateUserLastLoginTime")){ sqlCmd.AddParameter("_userName",NpgsqlDbType.Varchar,userName); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Adds users default folder. /// </summary> /// <param name="folderName">Folder name.</param> /// <param name="permanent">Spcifies if folder is permanent, user can't delete it.</param> public void AddUsersDefaultFolder(string folderName,bool permanent) { ArgsValidator.ValidateFolder(folderName); using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_AddUsersDefaultFolder")){ sqlCmd.AddParameter("_folderName" ,NpgsqlDbType.Varchar,folderName); sqlCmd.AddParameter("_permanent ",NpgsqlDbType.Boolean ,permanent); DataSet ds = sqlCmd.Execute(); ds.Tables[0].TableName = "UsersDefaultFolders"; } }
/// <summary> /// Checks if user exists. /// </summary> /// <param name="userName">User name.</param> /// <returns>Returns true if user exists.</returns> public bool UserExists(string userName) { using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetUserProperties")){ sqlCmd.AddParameter("_userName",NpgsqlDbType.Varchar,userName); DataSet ds = sqlCmd.Execute(); ds.Tables[0].TableName = "Users"; if(ds.Tables["Users"].Rows.Count > 0){ return true; } } return false; }
/// <summary> /// Checks if specified user can access specified mailing list. /// There is one built-in user anyone, that represent all users (including anonymous). /// </summary> /// <param name="mailingListName">Mailing list name.</param> /// <param name="user">User name.</param> /// <returns></returns> public bool CanAccessMailingList(string mailingListName,string user) { /* Implementation notes: *) Ensure that mailing list exists. *) Check access. */ // Ensure that mailing list exists // Get mailing list ID string mailingListID = null; foreach(DataRowView drV in GetMailingLists("ALL")){ if(drV["MailingListName"].ToString().ToLower() == mailingListName.ToLower()){ mailingListID = drV["MailingListID"].ToString(); break; } } if(mailingListID == null){ throw new Exception("Invalid mailing list name, specified mailing list '" + mailingListName + "' doesn't exist !"); } // Check access WSqlCommand cmd = new WSqlCommand(m_ConStr,"select * from lsMailingListACL"); cmd.CommandType = CommandType.Text; DataSet dsMailingListACL = cmd.Execute(); dsMailingListACL.Tables[0].TableName = "ACL"; foreach(DataRow dr in dsMailingListACL.Tables["ACL"].Rows){ if(dr["MailingListID"].ToString() == mailingListID){ // Built-in anyone if(dr["UserOrGroup"].ToString().ToLower() == "anyone"){ return true; } // Built-in "authenticated users" else if(dr["UserOrGroup"].ToString().ToLower() == "authenticated users"){ return UserExists(user); } // User or group else{ if(GroupExists(dr["UserOrGroup"].ToString())){ return IsUserGroupMember(dr["UserOrGroup"].ToString(),user); } else{ return UserExists(user); } } } } return false; }
/// <summary> /// Checks if specified mailbox size is exceeded. /// </summary> /// <param name="userName">User name. Use <see cref="IMailServerApi.GetUsers">GetUsers()</see> to get valid values.</param> /// <returns>Returns true if exceeded.</returns> public bool ValidateMailboxSize(string userName) { using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_ValidateMailboxSize")){ sqlCmd.AddParameter("_userName",NpgsqlDbType.Varchar,userName); DataSet ds = sqlCmd.Execute(); return (bool)sqlCmd.ExecuteScalar(); } }
/// <summary> /// Deletes specified domain. /// </summary> /// <param name="domainID">Domain ID. Use <see cref="IMailServerApi.GetDomains">GetDomains()</see> to get valid values.</param> /// <remarks>Deletes specified domain and all domain related data (users,mailing lists,routes).</remarks> public void DeleteDomain(string domainID) { using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_DeleteDomain")){ sqlCmd.AddParameter("_domainID" ,NpgsqlDbType.Varchar,domainID); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Gets all folders IMAP acl entries. /// </summary> /// <returns></returns> private DataSet GetACL() { using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"select * from lsIMAP_ACL")){ DataSet ds = sqlCmd.Execute(); ds.Tables[0].TableName = "ACL"; return ds; } }
/// <summary> /// Deletes IMAP folder. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what to delete. For example: Inbox,Public Folders/Documnets .</param> public void DeleteFolder(string accessingUser,string folderOwnerUser,string folder) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Don't allow to delete shared folders root folder. For BoundedUser root don't allow root folder only, for UsersShared root don't allow root + user name. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'c' permission. There is builtin user system, skip ACL for it. *) Create folder. */ // Don't allow to delete inbox if(folder.ToLower() == "inbox"){ throw new Exception("Can't delete inbox"); } //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; /* Don't allow to delete shared folders root folder. For BoundedUser root don't allow root folder only, for UsersShared root don't allow root + user name. */ // Main shared folder root. if(mappedFolder.SharedRootName.ToLower() == originalFolder.ToLower()){ throw new ArgumentException("Can't delete shared root folder '" + originalFolder + "' !"); } // Users shared folder: root/username -> no folder if(folder == ""){ throw new ArgumentException("Can't delete shared root folder '" + originalFolder + "' !"); } if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder doesn't exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'c' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.c) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Recycle bin handling ----------------------------------------------------------------------// if(Convert.ToBoolean(GetRecycleBinSettings().Rows[0]["DeleteToRecycleBin"])){ IMAP_MessageCollection messages = new IMAP_MessageCollection(); GetMessagesInfo("system",folderOwnerUser,folder,messages); foreach(IMAP_Message message in messages){ EmailMessageItems msgItems = new EmailMessageItems(message.ID,IMAP_MessageItems_enum.Message); GetMessageItems("system",folderOwnerUser,folder,msgItems); if(msgItems.MessageExists){ string subject = "<none>"; try{ subject = MimeUtils.ParseHeaderField("Subject:",msgItems.MessageStream); subject = subject.Replace("\r",""); subject = subject.Replace("\n",""); } catch{ } msgItems.MessageStream.Position = 0; byte[] data = new byte[msgItems.MessageStream.Length]; msgItems.MessageStream.Read(data,0,data.Length); using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreRecycleBinMessage")){ sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,Guid.NewGuid().ToString()); sqlCmd.AddParameter("_user" ,NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar,folder); sqlCmd.AddParameter("_subject" ,NpgsqlDbType.Varchar,subject); sqlCmd.AddParameter("_data" ,NpgsqlDbType.Bytea ,data); DataSet ds = sqlCmd.Execute(); } } } } //----------------------------------------------------------------------------------------------// //--- Delete folder using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_DeleteFolder")){ sqlCmd.AddParameter("_folderOwnerUser",NpgsqlDbType.Varchar,folderOwnerUser); sqlCmd.AddParameter("_folderName" ,NpgsqlDbType.Varchar,folder); DataSet ds = sqlCmd.Execute(); } }
/// <summary> /// Stores message to specified folder. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder where to store message. For example: Inbox,Public Folders/Documnets .</param> /// <param name="msgStream">Stream where message has stored. Stream position must be at the beginning of the message.</param> /// <param name="date">Recieve date.</param> /// <param name="flags">Message flags.</param> public void StoreMessage(string accessingUser,string folderOwnerUser,string folder,Stream msgStream,DateTime date,IMAP_MessageFlags flags) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'p' or 'i' permission. There is builtin user system, skip ACL for it. *) Store message. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(msgStream); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'p' or 'i' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.p) == 0 && (acl & IMAP_ACL_Flags.i) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Store message byte[] topLines = GetTopLines(msgStream,50); msgStream.Position = 0; byte[] messageData = new byte[msgStream.Length]; msgStream.Read(messageData,0,messageData.Length); Mime m = null; try{ msgStream.Position = 0; m = Mime.Parse(msgStream); } catch(Exception x){ m = LumiSoft.Net.Mime.Mime.CreateSimple(new AddressList(),new AddressList(),"[BAD MESSAGE] Bad message, message parsing failed !","NOTE: Bad message, message parsing failed !\r\n\r\n" + x.Message,""); } byte[] envelope = System.Text.Encoding.Default.GetBytes(IMAP_Envelope.ConstructEnvelope(m.MainEntity)); byte[] body = System.Text.Encoding.Default.GetBytes(IMAP_BODY.ConstructBodyStructure(m,false)); using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreMessage")){ sqlCmd.AddParameter("_userName" ,NpgsqlDbType.Varchar ,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar ,folder); sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar ,Guid.NewGuid().ToString()); sqlCmd.AddParameter("_size" ,NpgsqlDbType.Integer ,msgStream.Length); sqlCmd.AddParameter("_messageFlags" ,NpgsqlDbType.Integer ,(int)flags); sqlCmd.AddParameter("_date" ,NpgsqlDbType.Timestamp ,date); sqlCmd.AddParameter("_topLines" ,NpgsqlDbType.Bytea ,topLines); sqlCmd.AddParameter("_data" ,NpgsqlDbType.Bytea ,messageData); sqlCmd.AddParameter("_imapEnvelope" ,NpgsqlDbType.Bytea ,envelope); sqlCmd.AddParameter("_imapBody" ,NpgsqlDbType.Bytea ,body); DataSet ds = sqlCmd.Execute(); } }