I'm currently working on a .NET application that will be invoked from Lotus Notes 8.5. This .NET application is suppose to read some data from a Lotus Notes database, and export it to a file.
The code to connect to the Lotus Notes database is:
NotesSession ns = new NotesSession();
NotesView nv;
ns.Initialize("");
NotesDatabase nd = ns.GetDatabase("server", "file.nsf", false);
nv = nd.GetView("viewName");
Unfortunately, when ns.Initialize is invoked, the Lotus Notes component will prompt the user for their password. I understand that the method Initialize is overloaded, the user name and password can be provided. However, I will not know the username / password.
Since Lotus Notes will be open already, is there a way to access the Notes Database using the credentials of the user that is already logged into Lotus Notes? Essentially, I'd like to avoid having the user enter their Notes credentials again, but still access the database.
There is a setting that can be turned on in Notes in the User Security dialog. (You didn't mention the version of Lotus Notes. The dialog may be different if you're on an older version.) The setting is:
Don't prompt for a password from other Lotus Notes-based programs (reduces security).
Those last two words may be in parenthesis, but don't let that fool you. They are pretty important! The setting allows all programs running on that user's computer to use the Notes APIs without authentication. That opens the door for an email-borne piece of malware, amongst other threats. And never mind the fact that such threats have been rare in the Lotus Notes world. A big part of the reason for that is that keeping this setting disabled is the default.
From what I've said above, I'm sure you can understand why there isn't an easy way to do what you want to do!
The only way to disable the password prompt specifically for your application will be to use the Lotus Notes C API's feature set known as Extension Manager. I.e., you write a C source file that is compiled into a DLL. Your DLL must be installed on all users' machines, and an entry must be made in the notes.ini file in order to have it loaded when the Notes core DLLs run. The help files for the C API include some sample code showing how to do the Notes-specific part of this. You'd have to figure out the details of identifying the fact that it was invoked for your application, and (if I remember correctly) you would also have to write code to prompt the user for their password once and be responsible for securely storing it somewhere where your DLL can retrieve and decrypt it whenever it needs it.
I did find another way to perform this, without having to turn the "Don't prompt for a password from other Lotus Notes-based programs (reduces security)." check box on.
System.Type objNotesType = System.Type.GetTypeFromProgID("Notes.NotesSession");
dynamic ns = System.Activator.CreateInstance(objNotesType);
dynamic nd = ns.GetDatabase(AppSettings.NotesServer, AppSettings.NotesReplicaID);
if (nd.IsOpen != true) nd.OpenByReplicaID(nd.Server, AppSettings.NotesReplicaID);
dynamic nv = nd.GetView(AppSettings.NotesView);
I've tested it, and it works. I am not prompted for a password, and when accessing the Notes Database, I am accessing it under the current user's credentials. Also, no COM references needed to be added to the project.
Related
I am writing a program, which is like a swiss army knife of tools that my colleagues need in their day to day work. One feature of this tool is, to be able to connect to a client remotely and control it.
We already have an application called Dameware Mini Remote Control, not written by us, that does this exact job. My application just starts this software in a process and hands over username and password, the user has entered beforehand.
In the documentation of the Dameware Tool, it says that the process should be called with these arguments:
"dwrcc.exe [-?|-?:] [-c:] [-h:] [-m:MachineName] [-u:UserName] [-p:Password | -p:"Password"] [-d:Domain] [-o:TCPport] [-s:SharedSecret] [-r:] [-vnc:] [-a:0|1|2] [-prxa:MRCproxyAddress] [-prxp:MRCproxyPort] [-prxsMRCproxySecret] [-v:] [-md:] [-i:n] [-x:] [-bh:CentralServerHostAddress] [-bpn: CentralServerPortNumber] [-bu:CentralServerUserName] [-bps:CentralServerUserPassword]"
My concern is that providing the password in the -p option is not secure, because it is basically plain text.
Here is the part of my code where i provide the command line arguments:
proc.StartInfo.Arguments = $"-c: -h: -x: -m:{TxtHostname} -d:{MainUI.Credentials.DomainName} -u:{MainUI.Credentials.UserName} -p:{LoginCredentials.Decrypt(MainUI.Credentials.EncryptedPassword)}";
Is there a secure way of handing over the password to the Dameware application inside the process?
Any suggestions are greatly appreciated.
This is not possible in general. If the only option is to pass the password via a command line parameter, you do only have this option.
However it would be possible if the target application supports another way of receiving the password. This is application specific and doesn't apply to every application.
As I'm not familiar with Dameware Mini Remote Control, I can't tell if such an option exists in this specific case.
I had some problems with using the authorization before so I got a brand new everything - new computer, new OS, fresh installation of VS, new app and DB in a new resource group on the Azure. The whole shabang.
I can confirm that I can log in to the Azure DB as the screenshots below show.
I can see the databases, tables, users etc.
The problem is that, although it works locally (using the default connection string provided automagically for me), it doesn't perform very well in the Azure (although I'm using the publish file from there). It said something about the file not being found and according to this answer, I needed to change the connection string.
After I've altered it, I get the following error. Please note that the firewall is open and that I can access the DB when I run the code of my applications. I feel that there's something that goes wrong when the authentication part is automatically configured. I'm out of ideas on how to trouble-shoot it, though.
[SqlException (0x80131904): Login failed for user 'Chamster'.
This session has been assigned a tracing ID of '09121235-87f3-4a92-a371-50bc475306ca'. Provide this tracing ID to customer support when you need assistance.]
The connection string I'm using is this.
Server=tcp:f8goq0bvq7.database.windows.net,1433;
Database=Squicker;
User ID=Chamster#f8goq0bvq7;
Password=Abc123();
Encrypt=True;
TrustServerCertificate=False;
Connection Timeout=10;
This issue's bothered me for a while and I'll be bounting it in two days. Any suggestion's warmly appreciated.
I believe I've managed to resolve this weird issue. It appears that the user I'm using, despite being admin with all bells and whistles isn't recognized as admin when used in the connection string and trying to create the tables (which is the case at the first registration).
My solution was to create two logins - one with db_owner role and one with db_datareader and db_datawriter. First, I've used the elevated user in my connection string and registered a single user. That created the tables in the database as shown below.
Then, while able to continue as admin, I realized that we should try the demoted user and tada!, it worked perfectly. Once the tables were there, the whole shabeling behaved as expected.
To be perfectly sure, I dropped the tables from the database and there it was - the same issues as before. When I changed to the elevated user, the tables were restored allowing me to get back to the demoted one.
I also tried dropping the tables, confirming the issues to re-appear and then creating the tables manually. That works too! So basically,the only gotcha that caused it all was the original admin who's not treated as admin.
It might have to do with the fact that my Azure account's getting a bit old, LiveID used there is ancient and that didn't have an updated version of DB in Azure (the pull-up to v12 was carried out the 18th of December, so it's possible that it also was a requirement to get it working). I'm too tired and lazy to check that out and I realize that I've no idea how to get an "old" type of account. Besides, the issue will decrease and gradually vanish because the old accounts get upgraded eventually.
I am replacing MS Word MergeFields with data from SQL Server in a simple asp.net c# application and it works fine locally but when i publish it often i get the following:
System.Runtime.InteropServices.COMException (0x80080005): Retrieving the COM class factory for component with CLSID {00020906-0000-0000-C000-000000000046} failed due to the following error: 80080005.
I tried giving both IIS_IUSRS and NETWORK SERVICE full access, and also set the identity to interactive in the DCOM config but it didn't fix anything.
For nasty permissions stopping you from doing what you expect, (I've encountered in the past too). Sometimes I've had to change my DCOM/COM+ permissions to an object too. At the DCOM Config tab screen for your project, under security, make sure BOTH "Launch and Activation" and "Access" have been customized to explicitly include the user account you intend to allow.
Now, one more thing -- just to rule out all others. I've even gone the extent (for testing / confirmation only) is that on the "Identity" tab, you can select the "Interactive User", "Launching User" or "This User". I would put in your actual account that you KNOW has permissions (ensure your account is also in the launch and activation... and access permissions on previous tab). And also to enter/confirm your password.
If that still fails, then I would try adding the ADMIN account for permissions and try that... just for purposes of yes, its permissions based on a user. Once confirmed, you can scale it back, and even create some simplified restricted user who's primary purpose is to run this utility, and this new user has its adequate permissions to do so.
Once that is done, you should be good to go.
Now, that said, I've run into another flakey thing and its been a while, so it may not be an issue any more. Periodically, during certain "Windows" updates, the functionality would just stop working. However, if all I did was go back into user maintenance, do change password for the account (even if just keeping it the same original password) and saving it, then going back into DCOM and enter/re-confirm saving it there too, all became functional again.
You should share the folder where you save the document that is created from the template with the NETWORK SERVICE user.
Change the dcomcnfg identity to interactive instead of launching user.
Reference: Error : 80070005, there is something in this forum about
Retrieving the COM class factory for component with CLSID {7979FAA5-3A2A-4E50-A2C9-286C6F34C1D3} failed due to the following error: 80080005
I have an automation addin for excel developed using C#. How do I package and distribute it ? Also when the addin is installed for the first time, I want a username and password check to pop for the first time.
How can I go about doing this ?
thanks
Visual Studio creates a setup project for each Add-in project. You could start by using that. It produces an MSI file that you can distribute.
About the second part - if you stay with Studio-generated setup you probably cannot add custom dialogs to installation. You'll need some tool that builds the installations.
How about asking for username and password on the first use? This way the installation remains simple. In my experience every question during installation increases the risk that the user says "WTF, why do I have to answer these stupid questions. Cancel".
To ask for username and password on the first use only you have to save them somewhere after asking, so that next time you know them. Approved Microsoft way is saving them in Settings. By default Studio creates Settings file in your peoject just for that. Just add two variables to that file with empty default values. Mark them as User variables (not the Application variables).
From your add-in, access them as Properties.Setings.VariableName.
When your add-in starts, check if you have the username and password in settings. If they are empty, ask and save.
if (string.IsNullOrEmpty(Properties.Settings.Default.UserName))
{
string name;
string password;
//ask for name and password, replace with your code
AskForUserandPassword(out name, out password);
Properties.Settings.Default.UserName=name;
Properties.Settings.Default.Password=password;
Properties.Settings.Default.Save()
}
Physically, this is saved somewhere deep in user directory in an XML file.
The code I am currently working on runs on Windows Server 2003, but needs to be able to write to EventLogs on multiple machines. I am coding in C#, using VS2008 Pro, and .NET Framework 3.5.
The code itself is relatively simple (thanks to the framework):
using (EventLog remoteEvtLog = new EventLog(LogName, HostName, EventSource))
{
remoteEvtLog.WriteEntry(Body);
}
"LogName" is a string containing the name of the log to write to - in most cases "Application".
"HostName" is a string containing the NetBIOS Name of the machine where the log entry should be written.
"EventSource" is a string containing the name of the event sender (this is a utility used by multiple apps, so usually it will have the name of the consuming application).
"Body" is a string containing the text to be written to the event log.
In most cases this works fine, but when the machine being written to uses UAC, any write which creates a new EventSource fails. This occurs even though the Security credentials used are members of the Administrators group - and I have not been able to find a way to specify the elevated priviledge level. Apparently, members of the Administrators goroup get two tokens - one limited, and one elevated, but as far as I can tell, the only way to specifiy the elevated token is through the UI - which is obviously a problem when remotely accessing the Logs.
Any ideas out there?
Your code is not supposed to create new event sources (the legacy auto-create behavior is unfortunate, but still wrong). If you need a separate event source for your application, then the installer for that application - which runs with elevated administrative privileges - should create it.