CDO.Message giving "Access denied" on Windows Server 2008 - windows-server-2008

I have a Classic ASP page that creates a CDO.Message object to send email. The code works on Window Server 2003 but not 2008. On 2008 an "Access is denied" error gets thrown. Here is a simple test page I wrote to diagnose the problem. How can I get this to work on Windows Server 2008?
dim myMail
Set myMail=CreateObject("CDO.Message")
If Err.Number <> 0 Then
Response.Write ("Error Occurred: ")
Response.Write (Err.Description)
Else
Response.Write ("CDO.Message was created")
myMail.Subject="Sending email with CDO"
myMail.From="sender#mycompany.com"
myMail.To="recipient#mycompany.com"
myMail.TextBody="This is a message."
myMail.Send
set myMail=nothing
End If

I never got the CDO.Message object to work on Windows Server 2008. However, I found a workaround. I wrote an email class that works on Windows Server 2008. Hope this helps someone else.
[ComVisible(true)]
public class Email
{
public bool SendEmail(string strTo, string strFrom , string strSubject, string strBody)
{
bool result = false;
try
{
MailMessage message = new MailMessage();
SmtpClient client = new SmtpClient("smtp.mycompany.com");
List<string> to = recipientList(strTo);
foreach (string item in to)
{
message.To.Add(new MailAddress(item));
}
message.From = new MailAddress(strFrom);
message.Subject = strSubject;
message.Body = strBody;
client.Send(message);
result = true;
}
catch
{
result = false;
throw;
}
return result;
}
private List<string> recipientList(string strTo)
{
List<string> result = new List<string>();
string[] emailAddresses = strTo.Split(new Char[]{',',';'});
foreach (string email in emailAddresses)
{
result.Add(email.Trim());
}
return result;
}
}

As long as you're using the Microsoft SMTP server(1) you can use the IIS Metabase Explorer to give the IIS_USRS group(2) read read access to the /LM/SmtpSvc/ and /LM/SmtpSvc/1/ nodes in the IIS Metabase.
Unfortunately this solution doesn't apply to Windows 7. Microsoft does not ship an SMTP server with Windows 7, making it very difficult to get around this problem without refactoring your code.
(1) See http://www.itsolutionskb.com/2008/11/installing-and-configuring-windows-server-2008-smtp-server
(2) See http://blogs.msdn.com/b/akashb/archive/2010/05/24/error-cdo-message-1-0x80040220-the-quot-sendusing-quot-configuration-value-is-invalid-on-iis-7-5.aspx

Related

How to send email to different recipient with a different set of data in SSIS or by SQL?

Please suggest me how to achieved this:
The other table having set of data which I need to send:
Now by using SSIS we have to send the set of data to that email. In production I'm having 135 emails and have send them a separate data which contain their set of area.
#pp#gmial.cpm will get only data where subject is maths.
I have no idea to create variable of how to pass variable.
Can any one help me with this?
I use this method a lot for sending emails:
public static void SendEmail(List<string> to, string subject, string body, string filepathName = null)
{
using (MailMessage mail = new MailMessage())
{
string from = ConfigurationManager.AppSettings["EmailFrom"];
SmtpClient SmtpServer = new SmtpClient("your email server");
mail.From = new MailAddress(from);
foreach(string t in to)
mail.To.Add(new MailAddress(t));
mail.Subject = subject;
mail.ReplyToList.Add("your reply to email");
mail.IsBodyHtml = true;
mail.Body = body;
mail.Bcc.Add("enter your email if you want to be copied");
if (filepathName != null)
{
Attachment file;
file = new Attachment(filepathName);
mail.Attachments.Add(file);
}
SmtpServer.Port = 2525; //this is unique to you
SmtpServer.Credentials = new NetworkCredential(from, ConfigurationManager.AppSettings["EmailPassword"]);
SmtpServer.EnableSsl = true;
SmtpServer.Send(mail);
}
}
This won't completely solve your problem but will give you option of sending HTML emails straight from SSIS Script task.
You won't be able to use configuration manager, you will need to "hard code" that.

SSRS Report executes directly but WCF ReportExporter.Export method returns null Result and no errors

I have a report that is hosted in SQL Server 2012 SSRS and it executes fine through the browser. I am trying to run it using WCF as a Service Reference for the SSRS 2005 asmx from a ASP.Net web project and return it as a PDF using the ReportExporter.Export() method; however, it is not returning a result at all and the warnings array is empty. So, how can I troubleshoot the process to see where the difficulty is? I did not find any errors in the SSRS Log file even when I set it to verbose; nor did I find any errors in the standard SQL Log.
Here is my code:
NOTE: the call ReportExporter.Export(..) is to a method that encapsulates the execution of the webServiceProxy to the Service Reference.
{
IList<SSRS_Reports.ParameterValue> parameters = new List<SSRS_Reports.ParameterValue>();
parameters.Add(new SSRS_Reports.ParameterValue { Name = "paramId", Value = _paramId.ToString() }); }
byte[] result = null;
string extension = string.Empty;
string mimeType = string.Empty;
string encoding = string.Empty;
string reportName = "/baseFolder/ReceiptReport";
SSRS_Reports.Warning[] warnings = null;
string[] streamIDs = null;
string uN = ConfigurationManager.AppSettings["rptUName"].ToString();
string uP = ConfigurationManager.AppSettings["rptPWD"].ToString();
string uD = ConfigurationManager.AppSettings["rptDomain"].ToString();
//NOTE: the call "ReportExporter.Export(..) is to a method that encapsulates the execution of the webServiceProxy to the Service Reference.
ReportExporter.Export("ReportExecutionServiceSoap",
new System.Net.NetworkCredential(uN, uP, uD),
reportName,
parameters.ToArray(),
ExportFormat.PDF,
out result,
out extension,
out mimeType,
out encoding,
out warnings,
out streamIDs);
if (result != null)
{
//create a file and then show in browser
_mPDFFile = randomName() + ".pdf";
_mPDFPath = HttpRuntime.AppDomainAppPath + "\\pdf\\" + _mPDFFile;
//clear files older than today
Lib.FileManager.ManageFiles(HttpRuntime.AppDomainAppPath + "\\pdf", "*.pdf", -1);
if (File.Exists(_mPDFPath))
{
File.Delete(_mPDFPath);
}
FileStream stream = File.Create(_mPDFPath, result.Length);
stream.Write(result, 0, result.Length);
stream.Close();
return true;
}
}

Adobe Echo Sign Sending PDF file

I am working on Adobe Echo sign,I have downloaded the sample code from their website, I am using this sample code for sendingdocument, it has some code missing in sendDocument method so I have changed it. It's giving SoapHeader Exception,with nothing in InnerException,
{"apiActionId=XHZI4WF4BV693YS"}
below is my code of sending document
public static void sendDocument(string apiKey, string fileName, string recipient)
{
ES = new EchoSignDocumentService16();
FileStream file = File.OpenRead(fileName);
secure.echosign.com.FileInfo[] fileInfos = new secure.echosign.com.FileInfo[1];
fileInfos[0] = new secure.echosign.com.FileInfo(fileName, null, file);
SenderInfo senderInfo = null;
string[] recipients = new string[1];
recipients[0] = recipient;
DocumentCreationInfo documentInfo = new DocumentCreationInfo(
recipients,
"Test from SOAP: " + fileName,
"This is neat.",
fileInfos,
SignatureType.ESIGN,
SignatureFlow.SENDER_SIGNATURE_NOT_REQUIRED
);
DocumentKey[] documentKeys;
senderInfo = new SenderInfo(recipient, "password", "APIKEY");
documentKeys = ES.sendDocument(apiKey, senderInfo, documentInfo);
Console.WriteLine("Document key is: " + documentKeys[0].documentKey);
}
its giving exception on this line
documentKeys = ES.sendDocument(apiKey, senderInfo, documentInfo);
Can anyone suggest some sample code of Adobe Echo Sign?
On the account page of your login there is an API log you can check. If you check the log entry for your request you may find more information there.
I can't see anything immediately wrong with your code however the EchoSign API guide says that the 'tos' field is deprecated and that the recipients field should be used instead. Helpfully this means you can't use the paramaterised constructor. Try creating your document creation info as such (this is C# but if you need Java it should be straightforward to figure out):
RecipientInfo[] recipientInfo = new RecipientInfo[1];
recipientInfo[0] = new RecipientInfo
{
email = "recipient",
role = RecipientRole.SIGNER,
roleSpecified = true
};
DocumentCreationInfo documentCreationInfo = new DocumentCreationInfo
{
recipients = recipientInfo,
name = "Test from SOAP: " + fileName,
message = "This is neat.",
fileInfos = fileInfos,
signatureType = SignatureType.ESIGN,
signatureFlow = SignatureFlow.SENDER_SIGNATURE_NOT_REQUIRED
};
Note that when using the recipientInfo array it seems that the roleSpecified field must be set to true. This little field tripped me up for ages and I was receiving errors similar to yours.

Determining local security policy with xp_regread [duplicate]

I'm writing a C# program that will enforce password complexity in accordance with the Windows Group Policy setting "Password must meet complexity requirements". Specifically, if that policy is set to Enabled either on the local machine (if it's not part of a domain) or by the Domain Security Policy (for domain members), then my software needs to enforce a complex password for its own internal security.
The issue is that I can't figure out how to read that GPO setting. Google searches have indicated that I can read GPO settings with one of these two APIs: the System.DirectoryServices library in .NET Framework, and Windows Management Instrumentation (WMI), but I haven't had any success so far.
Any insights would be helpful.
There doesn't appear to be a documented API for this task, managed or otherwise.
Managed Attempt
I tried the managed route using the System.Management assembly:
ConnectionOptions options = new ConnectionOptions();
ManagementScope scope = new ManagementScope(#"\\.\root\RSOP\Computer", options);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, new ObjectQuery("SELECT * FROM RSOP_SecuritySettingBoolean"));
foreach(ManagementObject o in searcher.Get())
{
Console.WriteLine("Key Name: {0}", o["KeyName"]);
Console.WriteLine("Precedence: {0}", o["Precedence"]);
Console.WriteLine("Setting: {0}", o["Setting"]);
}
This however will not return results. It doesn't appear to be a permission issue as providing a username/password pair to ConnectionOptions results in an exception telling you that you can not specify a username when connecting locally.
Unmanaged Attempt
I looked at NetUserModalsGet. While this will return some information on password settings:
typedef struct _USER_MODALS_INFO_0 {
DWORD usrmod0_min_passwd_len;
DWORD usrmod0_max_passwd_age;
DWORD usrmod0_min_passwd_age;
DWORD usrmod0_force_logoff;
DWORD usrmod0_password_hist_len;
} USER_MODALS_INFO_0, *PUSER_MODALS_INFO_0, *LPUSER_MODALS_INFO_0;
..it will not let tell if the Password Complexity policy is enabled.
Tool Output Scraping 'Success'
So I resorted to parsing secedit.exe output.
public static bool PasswordComplexityPolicy()
{
var tempFile = Path.GetTempFileName();
Process p = new Process();
p.StartInfo.FileName = Environment.ExpandEnvironmentVariables(#"%SystemRoot%\system32\secedit.exe");
p.StartInfo.Arguments = String.Format(#"/export /cfg ""{0}"" /quiet", tempFile);
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.Start();
p.WaitForExit();
var file = IniFile.Load(tempFile);
IniSection systemAccess = null;
var passwordComplexityString = "";
var passwordComplexity = 0;
return file.Sections.TryGetValue("System Access", out systemAccess)
&& systemAccess.TryGetValue("PasswordComplexity", out passwordComplexityString)
&& Int32.TryParse(passwordComplexityString, out passwordComplexity)
&& passwordComplexity == 1;
}
Full code here: http://gist.github.com/421802
You can use the Resultant Set of Policy (RSOP) tools. E.g. here's a VBScript (lifted from here) which will tell you what you need to know. It should be simple enough to translate this into C#.
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\rsop\computer")
Set colItems = objWMIService.ExecQuery _
("Select * from RSOP_SecuritySettingBoolean")
For Each objItem in colItems
Wscript.Echo "Key Name: " & objItem.KeyName
Wscript.Echo "Precedence: " & objItem.Precedence
Wscript.Echo "Setting: " & objItem.Setting
Wscript.Echo
Next
I came across your this Microsoft forum answer http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/f3f5a61f-2ab9-459e-a1ee-c187465198e0
Hope this helps somebody who comes across this question in the future.

How do I programmatically tell if a client machine has the Microsoft.Jet.OLEDB.4.0 as a valid provider?

I need to export data into an Access database. My code works, but it works with the assumption the client machine has the Microsoft.Jet.OLEDB.4.0 as a valid provider.
I want to test to see if this is true or not, in code. My problem is that I don't have the location of an existing access database and I don't want to create a new .mdb that I'd use to verify the connection and then delete it.
Is there any way to tell which providers are installed?
You could simply check for the existence of
HKEY_CLASSES_ROOT\CLSID\{dee35070-506b-11cf-b1aa-00aa00b8de95}
which is the CLSID of Microsoft.Jet.OLEDB.4.0.
you could try to detect the MDAC version on the machine and based on that extrapolate if your provider is supported?
http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=47262&lngWId=1
here's a snippet you can take a look at.
Each major provider has classid mentioned under the registry editor
Ex:-
HKEY_CLASSES_ROOT\CLSID{dee35070-506b-11cf-b1aa-00aa00b8de95}
which is the CLSID of Microsoft.Jet.OLEDB.4.0.
To check programmatically, use below c# code, its checked on framework 2.0
using System.Data.OleDb;
OleDbEnumerator enumerator = new OleDbEnumerator();
DataTable table = enumerator.GetElements();
bool bNameFound = false;
bool bCLSIDFound = false;
foreach (DataRow row in table.Rows)
{
foreach (DataColumn col in table.Columns)
{
if ((col.ColumnName.Contains("SOURCES_CLSID")) && (row[col].ToString().Contains("{dee35070-506b-11cf-b1aa-00aa00b8de95}")))
Console.WriteLine("CLSID of Microsoft.Jet.OLEDB.4.0. Found");
if ((col.ColumnName.Contains("SOURCES_NAME")) && (row[col].ToString().Contains("Microsoft.ACE.OLEDB.12.0")))
{
bNameFound = true;
if ((col.ColumnName.Contains("SOURCES_CLSID")) && (row[col].ToString().Contains("{3BE786A0-0366-4F5C-9434-25CF162E475E}")))
bCLSIDFound = true;
}
}
}
if (!bNameFound && !bCLSIDFound)
Console.WriteLine("Microsoft.ACE.OLEDB.12.0 Not found");
else
Console.WriteLine("Microsoft.ACE.OLEDB.12.0 found");
Remember "Fix it right & not let the test bugs bite"
I believe if you have the .NET Framework installed (needed to run VB.NET Code) then the machine has the provider you mention. MSDN
Dim reader As Object = OleDbEnumerator.GetRootEnumerator()
Dim Oleprovide As String = ""
While reader.Read
For i = 0 To reader.FieldCount - 1
If reader.GetName(i) = "SOURCES_NAME" Then
If reader.GetValue(i).ToString.Contains(".OLEDB.") = True Then
Oleprovide = reader.GetValue(i).ToString
Exit For
End If
End If
Next
End While
reader.Close()
Dim MyConnection As OleDbConnection
MyConnection = New OleDbConnection("Provider=" & Oleprovide & ";Data Source=" & existingFile.FullName & ";Extended Properties=""Excel 13.0 Xml;HDR=Yes""")
MyConnection.Open()