Connecting from .NET to MQ-Series - ibm-mq

There are similar questions to this one, but not quite the same...
I have a C# program that is using amqmdnet.dll (from 9.0.1.0 MQC Redist)
The code to connect is:
Hashtable mqProperties = new Hashtable();
mqProperties.Add(MQC.CHANNEL_PROPERTY, channelName);
mqProperties.Add(MQC.HOST_NAME_PROPERTY, hostname);
mqProperties.Add(MQC.PORT_PROPERTY, port);
queueManager = new MQQueueManager(strQueueManagerName, mqProperties);
It works fine and writes to the queue. I assume it picks up my current login id from Windows.
When I run the same code on IIS, it connects but fails with an auth error 2035 when trying to write to the Queue.I assume this is because IIS is running as a different user-id.
I tried adding:
mqProperties.Add(MQC.USER_ID_PROPERTY, "myuserid");
mqProperties.Add(MQC.PASSWORD_PROPERTY, "mypassword");
and it did not work. Trying "mydomain\myuserid" did not work either. Some other posts mentioned that MQ needs the Windows SID. I tried using that string, but that did not work either.
At this point, I am playing with this, so I'd prefer not to ask the admins to set up a new userid on the MQ server side. With this in mind, is there any way I can login when running under the IIS user, but pass in my userid/password or some other credential to make this work?

If the queue manager is v8.0 or later and is configured to use CONNAUTH and has ADOPTCTX(YES) set you can present an id and password. If it does not have this set then the value presented in the UserId and Password property of a .NET client will be ignored.
A IBM developerWorks MQdev blog post "MQCSP Password Protection in MQ V8 has details on how to do this in various languages."
For .NET you should be able to use what you have with the addition of the MQC.USE_MQCSP_AUTHENTICATION_PROPERTY set to true:
mqProperties.Add(MQC.USER_ID_PROPERTY, "myuserid");
mqProperties.Add(MQC.PASSWORD_PROPERTY, "mypassword");
mqProperties.Add(MQC.USE_MQCSP_AUTHENTICATION_PROPERTY, true);
The queue manager will then authenticate this ID. If the queue manager is set with ADOPTCTX(YES) then it will always use the authenticated ID for OAM checks. If it is set to ADOPTCTX(NO) it will still use the ID the process is running under to perform OAM checks. It is highly recommended that this be set to ADOPTCTX(YES).
Update 2017/02/20:
Related to the comment "I can see that it might be turned off by admins so that MQ relies on the larger organizational SSO infrastructure.". Without setting up CONNAUTH and ADOPTCTX(YES) you can assert any id you want to over the channel. If a CHLAUTH rule is not in place to block administrative users then you can obtain full MQ administrative authority without any form of authentication.

Related

How to connect to remote Queue Manager using MQExplorer 8.0

I installed MQ8.0.0.4 on a ubuntu(14.4) server. I am able to launch a local MQ explorer and connect to local Queue Managers. I want to connect to the same Queue Manager from a remote windows machine. When I try this I get authorization errors:
Access not permitted. You are not authorized to perform this operation. (AMQ4036)
Access not permitted. You are not authorized to perform this operation. (AMQ4036)
Severity: 10 (Warning)
Explanation: The queue manager security mechanism has indicated that the userid associated with this request is not authorized to access the object.
This link shows a list of auth commands to enable remote windows connection, but the page only lists upto version 7.5 for which this is applicable. Will I have to do the same setup on 8.0 as well?
I already enabled remote administration using the local MQ Explorer.
"The queue manager security mechanism has indicated that the userid associated with this request is not authorized to access the object." Are you using the mqm ID or another ID? You could use the MQS_REPORT_NOAUTH or MQSAUTHERRORS setting to get more info the authority failure.
To answer your other question, I believe the settings in the link will also apply to v8 - but v8 also has additional new authority checks as well.

Make Win7 use new password without reboot or screen unlock

We call DirectoryEntry.Invoke("SetPassword",newpwd) to change the password of a local user, but the new password is not being used immediately when doing Windows Authentication to a remote SQL server. It does get used after a reboot, but that's not really an option for me here. How can I make it take effect without rebooting? I need currently running processes on the client to begin using the new password immediately.
The environment is two Windows 7 Embedded systems, call them 'server' and 'client', and there is no domain, but they are both in the same workgroup. We use the same username on both systems. There are multiple servers out there with different passwords (computed based on various things). When we need to switch to use a different server, we change the password locally. The change itself is successful, but SQL accesses from client to server fail with
SSPI handshake failed with error code 0x8009030c, state 14 while establishing a connection with integrated security; the connection has been closed. Reason: AcceptSecurityContext failed. The Windows error code indicates the cause of failure.
and
Login failed. The login is from an untrusted domain and cannot be used with Windows authentication.
But as soon as client reboots it can access server's database successfully.
SQL Express 2008 on both systems, configured to use only Windows Authentication.
Wireshark shows me the SMB2 NTLMSSP_AUTH packet with what looks like the usual info although I don't know how to decode the security blob. Otherwise it matches the packet from a successful session. In the failure case this packet is followed by an SMB2 response with STATUS_LOGON_FAILURE and a missing security blob. I can only think that the client presents some kind of hash of the password in that security blob and the server is finding that it doesn't match its own password hash - or something like that.
Changing the environment ('Use Active Directory', 'Use Kerberos', etc.) is unfortunately not an option for me here. Also, these are consumer touch-screen kiosks, where no human ever knows the password, and wouldn't have a keyboard to enter it anyway.
ADD: FYI, The changing of the password is done thus:
DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("WinNT://localhost/{0}", username));
directoryEntry.Invoke("SetPassword", newPassword);
ADD: Made that parameter new object[] {newPassword}, and called .CommitChanges(), because those look like correct things to do. No change in behavior.

What is security property 'Server user identity' used for in Websphere Application Server?

When configuring the global security for Websphere Application Server, no matter you choose Federated Repositories, LDAP registry or custom registry, there is a property named 'Server user identity' to be setup. According to the official explanation, this is used for authentication during server to server communication. Does it mean when server communicating with each other within one cell, authentication is required and this value would be used there? And does this value only impact internal process, like within same cell? Or it can also be between cells? If it's not leveraged like this way, then how does 'Server user identity' work?
Kinda don't understand this. Please help me figure it out. Thanks in advance
Until WAS 6, a single user identity was required, namely 'primary administrative user', for both administrative access and internal process communication . This user, by definition, had to exist on the configured user registry.
From version 6.1 onwards, WAS requires an administrative user, distinguished from the server user identity, so that administrative actions can be audited separately.
For all practical purposes, if you are using version 6.1+, and you are not in a mixed-release cell (cell containing profiles of older versions of WAS in addition to current versions), you may just go ahead with automatically generated internal user id. An internally-generated server ID also adds a further level of protection to the server environment because the server password is not exposed.
For mixed-release cells you may check infocenter here for details on how to configure server user id in this case.
Server user id is used for server to server communication in a cell. I could not find any documentation that implies this parameter is also related with cross cell communication.

Remote MQ Server Authentication

I am trying to figure out how we would configure / setup the authentication, Queues, and Queue managers for connecting an MQ Client that is on a server / domain completely separate from the MQ Server it will be forwarding messages to.
I would assume that in a normally organizational environment you could just use Active Directory (if hosted on windows servers) for the authentication / AD lookup. However, in this scenario because they are different orgs you couldn't do that?
Can you simply apply SSL certs to both client / server and use that as your authentication? If so is that just applied to the Channel used in the connections?
Not sure how to proceed forward with this.
Any suggestions would be greatly appreciated.
Thanks,
S
Take a look at the Hardening WebSphere MQ presentation for v7.0 and earlier. The thing to remember is that WMQ does not authenticate anything. It authorizes based on OS identities and groups but there is no password checking being done.
For situations where QMgrs and clients live on Windows networks, the connection uses the SID and so it appears that some useful authentication was performed. BUT if a connection from a non-Windows platform is attempted, the Windows QMgr uses the string representation of the ID. So for example, if someone has a Linux VM on their desktop they can easily create a user ID called MUSR_MQADMIN and the Windows QMgr will accept the connection. There is a setting that causes the Windows QMgr to only accept connections with SIDS that it can resolve but even there its just a matter of knowing what the SID values are to spoof them on a connection.
The lesson here is that any QMgr, even one on Windows, must be configured to authenticate remote connections. With WMQ v7.1 and later, the QMgr has functionality to map X.509 certificate DNs to user IDs, or to perform IP filtering. Prior to v7.1 these functions required an exit such as BlockIP2. Capitalware sells MQAUSX which has the functions of BlockIP2, plus will perform ID and password authentication and is supported.
The first recommendation is to use a v7.1 QMgr so that you get the CHLAUTH rules for mapping and filtering. Even if you don't use certificates v7.1 limits administrative connections so it is harder for an attacker to gain full admin rights. Then if you need password validation, use SSL channels (to encrypt the password and prevent simply replay attacks) in combination with an exit that you can write yourself or purchase.
Just be aware that allowing a connection from outside your domain doesn't present any new challenges. The pre-v7.1 Windows QMgr that does not have MCAUSER set in the channel definition or by an exit allows remote administrative access, even from connections originating in the local Windows domain. There was always a need to harden that QMgr, even though honest users will have received authorization errors if the administrator did not set up auths for them.
Summary:
For clients originating outside your administrative domain, I'd recommend mutually authenticated TLS/SSL channels. The same page I linked to above also contains the WMQ Security Lab guide and scripts which show how to script the creation and exchange of WMQ certs and configure WMQ Explorer with them.
Whatever else you do, the MCAUSER on any legitimate channel must be set either in the configuration or by an exit. If the client is allowed to specify the ID, there is nothing to prevent it from specifying an administrative ID. For channels that are NOT being used such as SYSTEM.DEF.* and SYSTEM.AUTO.*, set the MCAUSER to a value that cannot be a local ID such as no!body or on v7.1 and later *NOACCESS.

Pass current user credentials to remote server

I have an application server (webservice or remoting, not yet decided) on a remote machine and a client on the same domain. I want to authenticate the user as a domain user on the server.
I can ask the user to enter their Windows username/password and send those to the server and get the server to check them against Active Directory but I would rather not. Is there any way I can get the client to send some kind of token which the server can then use to identify which domain user is sending it a request? Obviously I want to protect the server against someone sending a fake user ID and impersonating another user.
Clarification
The client on computer A will communicate with the server on computer B. I think I will probably using .NET remoting for this communication. On the server I merely need to know the ID of the user on computer A; if the app on computer A must send the ID I need to be sure that it hasn't sent the ID of a different user.
I don't need to impersonate the other user, I merely need to know (for certain) who it is.
Are you saying that the client communicates against your server, and you need to use the client's privileges at a third server? That scenario describes The Double-Hop Problem. The blog most describes it in detail, and what can be done to circumvent it (domain modifications).
[...] you can get around the problem and use proper delegation if you set up your network to use Kerberos and set up the web server in question as trusted for delegation.
Added:
I know of no way you can identify the user on computer A. Would it be enough if it was just the user executing your program? You could use windows authentication in a domain scenario, but that would only give you the privileges used by the program to authenticate, which may differ from the actual evil user in front of the keyboard.
Added:
Your comments to this post indicates that windows authentication with impersonation would work for you. Check http://community.bartdesmet.net/blogs/bart/archive/2006/08/26/4277.aspx for code examples.

Resources