//Function to create domain level dirContext object public static DirectoryContext CreateDirectoryContext( string DomainControllerName, string rootDN, string UserName, string Password, int portNumber, bool usingSimpleBind, out string errorMessage) { int ret = -1; errorMessage = null; string sDomainControllerIP = null; IPHostEntry domainControllerEntry=null; try { if (DomainControllerName != null) { domainControllerEntry = Dns.GetHostEntry(DomainControllerName); } else { return null; } } catch(Exception ex) { errorMessage = String.Format( "The specified domain either does not exist or DNS could not resolve the address of the domain controller : {0}", DomainControllerName); Logger.Log("DirectoryContext.CreateDirectoryContext():" + ex.Message); Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); //Logger.ShowUserError(errorMessage); return null; } if (domainControllerEntry != null && domainControllerEntry.AddressList.Length > 0) { sDomainControllerIP = domainControllerEntry.AddressList[0].ToString(); } else { errorMessage = String.Format( "DirectoryContext.CreateDirectoryContext(): Could not resolve address of domain controller : {0}", DomainControllerName); //Logger.ShowUserError("DirectoryContext.CreateDirectoryContext(): Could not resolve address of domain controller: {0}"); Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); errorMessage = ""; return null; } IntPtr ld = LdapAPI.ldap_open(sDomainControllerIP, portNumber); if (ld == IntPtr.Zero) { errorMessage = "The specified domain either does not exist or could not be contacted. " + "Please contact your system administrator to verify that your domain is " + "properly configured and is currently online."; Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); errorMessage = ""; //Logger.ShowUserError(errorMessage); return null; } //LdapTimeVal timeout = new LdapTimeVal(1, 0); ////IntPtr ptrTimeout = IntPtr.Zero; ////ptrTimeout = Marshal.AllocHGlobal(Marshal.SizeOf(timeout)); ////Marshal.WriteInt32(ptrTimeout, timeout.); //ret = LdapAPI.ldap_connect(ld, timeout.ConvertToUM()); //if (BailOnLdapError("LdapAPI.ldap_connect :", ret, out errorMessage)) //{ // Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); // errorMessage = ""; // return null; //} LdapHandle ldapHandle = new LdapHandle(ld); string distinguishedName = string.Format("cn={0},cn=Users,{1}", UserName, rootDN); if (!String.IsNullOrEmpty(UserName) && !UserName.Equals("administrator", StringComparison.InvariantCultureIgnoreCase)) distinguishedName = UserName; int version = LDAP_VERSION3; IntPtr ptrVersion = IntPtr.Zero; ptrVersion = Marshal.AllocHGlobal(Marshal.SizeOf(version)); Marshal.WriteInt32(ptrVersion, version); ret = LdapAPI.ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, ptrVersion); if(BailOnLdapError("ldap_set_option OPT_PROTOCOL_VERSION :", ret, out errorMessage)) { Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); errorMessage = ""; return null; } ret = LdapAPI.ldap_set_option(ld, LDAP_OPT_REFERRALS, IntPtr.Zero); if(BailOnLdapError("ldap_set_option LDAP_OPT_REFERRALS :", ret, out errorMessage)) { Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); errorMessage = ""; return null; } if (!String.IsNullOrEmpty(Password)) { usingSimpleBind = Configurations.SSOFailed = true; } if (usingSimpleBind) { if (Configurations.currentPlatform == LikewiseTargetPlatform.Windows) { ret = LdapAPI.ldap_bind_s(ld, distinguishedName, Password, (ulong)LDAP_AUTHWindows.LDAP_AUTH_SIMPLE); } else { ret = LdapAPI.ldap_bind_s(ld, distinguishedName, Password, (ulong)LDAP_AUTHLinux.LDAP_AUTH_SIMPLE); } if (BailOnLdapError("", ret, out errorMessage)) { Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); return null; } } else /***GSS-bind***/ { if (Configurations.currentPlatform != LikewiseTargetPlatform.Windows) { //set GSS-Remote Principal Name //char ber_pvt_opt_on; /* used to get a non-NULL address for *_OPT_ON */ ///* option on/off values */ //#define LDAP_OPT_ON ((void *) &ber_pvt_opt_on) //#define LDAP_OPT_OFF ((void *) 0) //status = ldap_set_option(ld, LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL, LDAP_OPT_ON); char ber_pvt_opt_on = '1'; IntPtr ptrRemotePrincipalflags = IntPtr.Zero; ptrRemotePrincipalflags = Marshal.AllocHGlobal(Marshal.SizeOf(ber_pvt_opt_on)); Marshal.WriteInt32(ptrRemotePrincipalflags, ber_pvt_opt_on); ret = LdapAPI.ldap_set_option(ld, LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL, ptrRemotePrincipalflags); if (BailOnLdapError("DirectoryContext GSS-Bind: ldap_set_option LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL, ptrRemotePrincipalflags=" + ptrRemotePrincipalflags, ret, out errorMessage)) { Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); errorMessage = ""; return null; } } //set GSS-SPNEGO options int secflags = ISC_REQ_MUTUAL_AUTH | ISC_REQ_REPLAY_DETECT; IntPtr ptrSecflags = IntPtr.Zero; ptrSecflags = Marshal.AllocHGlobal(Marshal.SizeOf(secflags)); Marshal.WriteInt32(ptrSecflags, secflags); ret = LdapAPI.ldap_set_option(ld, LDAP_OPT_SSPI_FLAGS, ptrSecflags); if (BailOnLdapError("DirectoryContext GSS-Bind: ldap_set_option LDAP_OPT_SSPI_FLAGS, secflags=" + secflags, ret, out errorMessage)) { Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); errorMessage = ""; return null; } if (Configurations.currentPlatform != LikewiseTargetPlatform.Windows) { secflags |= ISC_REQ_INTEGRITY; ptrSecflags = IntPtr.Zero; ptrSecflags = Marshal.AllocHGlobal(Marshal.SizeOf(secflags)); Marshal.WriteInt32(ptrSecflags, secflags); ret = LdapAPI.ldap_set_option(ld, LDAP_OPT_SSPI_FLAGS, ptrSecflags); if (BailOnLdapError("DirectoryContext GSS-Bind: ldap_set_option LDAP_OPT_SSPI_FLAGS, secflags=" + secflags, ret, out errorMessage)) { Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); errorMessage = ""; return null; } secflags |= ISC_REQ_CONFIDENTIALITY; ptrSecflags = IntPtr.Zero; ptrSecflags = Marshal.AllocHGlobal(Marshal.SizeOf(secflags)); Marshal.WriteInt32(ptrSecflags, secflags); ret = LdapAPI.ldap_set_option(ld, LDAP_OPT_SSPI_FLAGS, ptrSecflags); if (BailOnLdapError("DirectoryContext GSS-Bind: ldap_set_option LDAP_OPT_SSPI_FLAGS, secflags=" + secflags, ret, out errorMessage)) { Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); errorMessage = ""; return null; } } if (Configurations.currentPlatform == LikewiseTargetPlatform.Windows) { ret = LdapAPI.ldap_bind_s(ld, null, null, (ulong)LDAP_AUTHWindows.LDAP_AUTH_NEGOTIATE); } else { ret = LdapAPI.ldap_bind_s(ld, null, null, (ulong)LDAP_AUTHLinux.LDAP_AUTH_NEGOTIATE); } if (BailOnLdapError("DirectoryContext GSS-Bind:ldap_bind_s :", ret, out errorMessage)) { Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); errorMessage = ""; return null; } } //try to figure out the DC that serves as GC string configurationName = null; //searching with baseDn="" allows ldap to access the domain “RootDSE”. //Without passing that, it cannot access the configurationNamingContext DirectoryContext dirContext = new DirectoryContext( DomainControllerName, rootDN, distinguishedName, UserName, Password, ldapHandle, portNumber); dirContext._domainControllerIP = sDomainControllerIP; LdapMessage ldapMessage; string gcServer = DomainControllerName; Logger.Log("root query is started querying ", Logger.ldapLogLevel); IntPtr MessagePtr; ret = LdapAPI.ldap_search_s(ld, "", (int)LdapAPI.LDAPSCOPE.BASE, "(objectClass=*)", null, 0, out MessagePtr); ldapMessage = new LdapMessage(ldapHandle, MessagePtr); Logger.Log("root query is finished querying " + ret, Logger.ldapLogLevel); List<LdapEntry> ldapEntries = (ldapMessage != null ? ldapMessage.Ldap_Get_Entries() : null); Logger.Log("root query is finished querying with ldapEntries count : " + ldapEntries, Logger.ldapLogLevel); #region //Obtaining RootDSE attributes if (ldapEntries != null && ldapEntries.Count > 0) { LdapEntry rootDseEntry = ldapEntries[0]; LdapValue[] values = rootDseEntry.GetAttributeValues("defaultNamingContext", dirContext); if (values != null && values.Length > 0) { dirContext.DefaultNamingContext = values[0].stringData; } Logger.Log("defaultNamingContext is " + dirContext.DefaultNamingContext, Logger.ldapLogLevel); values = rootDseEntry.GetAttributeValues("schemaNamingContext", dirContext); if (values != null && values.Length > 0) { dirContext.SchemaNamingContext = values[0].stringData; } Logger.Log("schemaNamingContext is " + dirContext.SchemaNamingContext, Logger.ldapLogLevel); values = rootDseEntry.GetAttributeValues("dnsHostName", dirContext); if (values != null && values.Length > 0) { dirContext.DnsHostName = values[0].stringData; } Logger.Log("dnsHostName is " + dirContext.DnsHostName, Logger.ldapLogLevel); values = rootDseEntry.GetAttributeValues("rootDomainNamingContext", dirContext); if (values != null && values.Length > 0) { dirContext.RootDomainNamingContext = values[0].stringData; } Logger.Log("dnsHostName is " + dirContext.RootDomainNamingContext, Logger.ldapLogLevel); values = rootDseEntry.GetAttributeValues("configurationNamingContext", dirContext); if (values != null && values.Length > 0) { configurationName = values[0].stringData; } Logger.Log( "configurationNamingContext is " + configurationName, Logger.ldapLogLevel); values = rootDseEntry.GetAttributeValues("SupportedSASLMechanisms", dirContext); if (values != null && values.Length > 0) { _supportedSASLMechanisms = new string[values.Length]; int index = 0; foreach (LdapValue value in values) { _supportedSASLMechanisms[index] = value.stringData; Logger.Log( "SupportedSASLMechanisms is " + value.stringData, Logger.ldapLogLevel); index++; } } dirContext.ConfigurationNamingContext = configurationName; #endregion ret = LdapAPI.ldap_search_s(ld, configurationName, (int)LdapAPI.LDAPSCOPE.BASE, "(&(objectcategory=ntdsdsa)(options=1))", new string[] { "distinguishedName", null }, 0, out MessagePtr); ldapMessage = new LdapMessage(ldapHandle, MessagePtr); if(BailOnLdapError("ldap_search_s :", ret, out errorMessage)) { Logger.Log("DirectoryContext.CreateDirectoryContext(): " + errorMessage); errorMessage = ""; return null; } ldapEntries = (ldapMessage != null ? ldapMessage.Ldap_Get_Entries() : null); if (ldapEntries != null && ldapEntries.Count > 0) { //we only check the first one, then we quit finding others (when we do optimization, this algorithm shall be a lot more complicated LdapEntry ldapNextEntry = ldapEntries[0]; values = ldapNextEntry.GetAttributeValues("distinguishedName", dirContext); if (values != null && values.Length > 0) { string dn = values[0].stringData; string[] splits1 = dn.Split(','); string[] splits2 = rootDN.Split(','); gcServer = splits1[1].Substring(3).ToLower(); foreach (string str in splits2) gcServer = string.Concat(gcServer, ".", str.Substring(3).ToLower()); Logger.Log( "global catelog server is " + gcServer, Logger.ldapLogLevel); } } } dirContext.GCServername = gcServer; dirContext.BindMethod = usingSimpleBind; ldapHandle.DirectoryContext = dirContext; return dirContext; }
protected DirectoryContext( string ServerName, string rootDN, string DistinguishedName, string UserName, string Password, LdapHandle ldapHandle, int portNumber) { _rootDN = rootDN; string[] domainDNcom = _rootDN.Split(','); string domainName = ""; foreach (string str in domainDNcom) { string temp = string.Concat(str.Substring(3), "."); domainName = string.Concat(domainName, temp); } domainName = domainName.Substring(0, domainName.Length - 1); _domainName = domainName; _domainControllerName = ServerName; _distinguishedName = DistinguishedName; _userName = UserName; _password = Password; _ldapHandle = new LdapHandle(ldapHandle.Handle, this); _portNumber = portNumber; }
public DirectoryContext(DirectoryContext dirContext) { _rootDN = dirContext.RootDN; string[] domainDNcom = _rootDN.Split(','); string domainName = ""; foreach (string str in domainDNcom) { string temp = string.Concat(str.Substring(3), "."); domainName = string.Concat(domainName, temp); } domainName = domainName.Substring(0, domainName.Length - 1); _domainName = domainName; _domainControllerName = dirContext.DomainControllerName; _distinguishedName = dirContext.DistinguishedName; _userName = dirContext.UserName; _password = dirContext.Password; _ldapHandle = new LdapHandle(dirContext.LdapHandle.Handle, this); _portNumber = dirContext.PortNumber; }
public LdapMessage(LdapHandle ldapHandle, IntPtr ldapMessage) { _ldapHandle = ldapHandle; _ldapMessage = ldapMessage; _dircontext = null; }