kanidm/docs/v1.0.0rc9/rustdoc/src/orca/ldap.rs.html
2022-10-07 09:23:12 +00:00

724 lines
48 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `orca/src/ldap.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>ldap.rs - source</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceSerif4-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../FiraSans-Regular.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../FiraSans-Medium.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceCodePro-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceSerif4-Bold.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../SourceCodePro-Semibold.ttf.woff2"><link rel="stylesheet" type="text/css" href="../../normalize.css"><link rel="stylesheet" type="text/css" href="../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../../ayu.css" disabled><link rel="stylesheet" type="text/css" href="../../dark.css" disabled><link rel="stylesheet" type="text/css" href="../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../storage.js"></script><script defer src="../../source-script.js"></script><script defer src="../../source-files.js"></script><script defer src="../../main.js"></script><noscript><link rel="stylesheet" href="../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../favicon.svg"></head><body class="rustdoc source"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle">&#9776;</button><a class="sidebar-logo" href="../../orca/index.html"><div class="logo-container"><img class="rust-logo" src="../../rust-logo.svg" alt="logo"></div></a><h2 class="location"></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../orca/index.html"><div class="logo-container"><img class="rust-logo" src="../../rust-logo.svg" alt="logo"></div></a></nav><main><div class="width-limiter"><div class="sub-container"><a class="sub-logo-container" href="../../orca/index.html"><img class="rust-logo" src="../../rust-logo.svg" alt="logo"></a><nav class="sub"><form class="search-form"><div class="search-container"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><button type="button">?</button></div><div id="settings-menu" tabindex="-1"><a href="../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../wheel.svg"></a></div></div></form></nav></div><section id="main-content" class="content"><div class="example-wrap"><pre class="line-numbers"><span id="1">1</span>
<span id="2">2</span>
<span id="3">3</span>
<span id="4">4</span>
<span id="5">5</span>
<span id="6">6</span>
<span id="7">7</span>
<span id="8">8</span>
<span id="9">9</span>
<span id="10">10</span>
<span id="11">11</span>
<span id="12">12</span>
<span id="13">13</span>
<span id="14">14</span>
<span id="15">15</span>
<span id="16">16</span>
<span id="17">17</span>
<span id="18">18</span>
<span id="19">19</span>
<span id="20">20</span>
<span id="21">21</span>
<span id="22">22</span>
<span id="23">23</span>
<span id="24">24</span>
<span id="25">25</span>
<span id="26">26</span>
<span id="27">27</span>
<span id="28">28</span>
<span id="29">29</span>
<span id="30">30</span>
<span id="31">31</span>
<span id="32">32</span>
<span id="33">33</span>
<span id="34">34</span>
<span id="35">35</span>
<span id="36">36</span>
<span id="37">37</span>
<span id="38">38</span>
<span id="39">39</span>
<span id="40">40</span>
<span id="41">41</span>
<span id="42">42</span>
<span id="43">43</span>
<span id="44">44</span>
<span id="45">45</span>
<span id="46">46</span>
<span id="47">47</span>
<span id="48">48</span>
<span id="49">49</span>
<span id="50">50</span>
<span id="51">51</span>
<span id="52">52</span>
<span id="53">53</span>
<span id="54">54</span>
<span id="55">55</span>
<span id="56">56</span>
<span id="57">57</span>
<span id="58">58</span>
<span id="59">59</span>
<span id="60">60</span>
<span id="61">61</span>
<span id="62">62</span>
<span id="63">63</span>
<span id="64">64</span>
<span id="65">65</span>
<span id="66">66</span>
<span id="67">67</span>
<span id="68">68</span>
<span id="69">69</span>
<span id="70">70</span>
<span id="71">71</span>
<span id="72">72</span>
<span id="73">73</span>
<span id="74">74</span>
<span id="75">75</span>
<span id="76">76</span>
<span id="77">77</span>
<span id="78">78</span>
<span id="79">79</span>
<span id="80">80</span>
<span id="81">81</span>
<span id="82">82</span>
<span id="83">83</span>
<span id="84">84</span>
<span id="85">85</span>
<span id="86">86</span>
<span id="87">87</span>
<span id="88">88</span>
<span id="89">89</span>
<span id="90">90</span>
<span id="91">91</span>
<span id="92">92</span>
<span id="93">93</span>
<span id="94">94</span>
<span id="95">95</span>
<span id="96">96</span>
<span id="97">97</span>
<span id="98">98</span>
<span id="99">99</span>
<span id="100">100</span>
<span id="101">101</span>
<span id="102">102</span>
<span id="103">103</span>
<span id="104">104</span>
<span id="105">105</span>
<span id="106">106</span>
<span id="107">107</span>
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
<span id="111">111</span>
<span id="112">112</span>
<span id="113">113</span>
<span id="114">114</span>
<span id="115">115</span>
<span id="116">116</span>
<span id="117">117</span>
<span id="118">118</span>
<span id="119">119</span>
<span id="120">120</span>
<span id="121">121</span>
<span id="122">122</span>
<span id="123">123</span>
<span id="124">124</span>
<span id="125">125</span>
<span id="126">126</span>
<span id="127">127</span>
<span id="128">128</span>
<span id="129">129</span>
<span id="130">130</span>
<span id="131">131</span>
<span id="132">132</span>
<span id="133">133</span>
<span id="134">134</span>
<span id="135">135</span>
<span id="136">136</span>
<span id="137">137</span>
<span id="138">138</span>
<span id="139">139</span>
<span id="140">140</span>
<span id="141">141</span>
<span id="142">142</span>
<span id="143">143</span>
<span id="144">144</span>
<span id="145">145</span>
<span id="146">146</span>
<span id="147">147</span>
<span id="148">148</span>
<span id="149">149</span>
<span id="150">150</span>
<span id="151">151</span>
<span id="152">152</span>
<span id="153">153</span>
<span id="154">154</span>
<span id="155">155</span>
<span id="156">156</span>
<span id="157">157</span>
<span id="158">158</span>
<span id="159">159</span>
<span id="160">160</span>
<span id="161">161</span>
<span id="162">162</span>
<span id="163">163</span>
<span id="164">164</span>
<span id="165">165</span>
<span id="166">166</span>
<span id="167">167</span>
<span id="168">168</span>
<span id="169">169</span>
<span id="170">170</span>
<span id="171">171</span>
<span id="172">172</span>
<span id="173">173</span>
<span id="174">174</span>
<span id="175">175</span>
<span id="176">176</span>
<span id="177">177</span>
<span id="178">178</span>
<span id="179">179</span>
<span id="180">180</span>
<span id="181">181</span>
<span id="182">182</span>
<span id="183">183</span>
<span id="184">184</span>
<span id="185">185</span>
<span id="186">186</span>
<span id="187">187</span>
<span id="188">188</span>
<span id="189">189</span>
<span id="190">190</span>
<span id="191">191</span>
<span id="192">192</span>
<span id="193">193</span>
<span id="194">194</span>
<span id="195">195</span>
<span id="196">196</span>
<span id="197">197</span>
<span id="198">198</span>
<span id="199">199</span>
<span id="200">200</span>
<span id="201">201</span>
<span id="202">202</span>
<span id="203">203</span>
<span id="204">204</span>
<span id="205">205</span>
<span id="206">206</span>
<span id="207">207</span>
<span id="208">208</span>
<span id="209">209</span>
<span id="210">210</span>
<span id="211">211</span>
<span id="212">212</span>
<span id="213">213</span>
<span id="214">214</span>
<span id="215">215</span>
<span id="216">216</span>
<span id="217">217</span>
<span id="218">218</span>
<span id="219">219</span>
<span id="220">220</span>
<span id="221">221</span>
<span id="222">222</span>
<span id="223">223</span>
<span id="224">224</span>
<span id="225">225</span>
<span id="226">226</span>
<span id="227">227</span>
<span id="228">228</span>
<span id="229">229</span>
<span id="230">230</span>
<span id="231">231</span>
<span id="232">232</span>
<span id="233">233</span>
<span id="234">234</span>
<span id="235">235</span>
<span id="236">236</span>
<span id="237">237</span>
<span id="238">238</span>
<span id="239">239</span>
<span id="240">240</span>
<span id="241">241</span>
<span id="242">242</span>
<span id="243">243</span>
<span id="244">244</span>
<span id="245">245</span>
<span id="246">246</span>
<span id="247">247</span>
<span id="248">248</span>
<span id="249">249</span>
<span id="250">250</span>
<span id="251">251</span>
<span id="252">252</span>
<span id="253">253</span>
<span id="254">254</span>
<span id="255">255</span>
<span id="256">256</span>
<span id="257">257</span>
<span id="258">258</span>
<span id="259">259</span>
<span id="260">260</span>
<span id="261">261</span>
<span id="262">262</span>
<span id="263">263</span>
<span id="264">264</span>
<span id="265">265</span>
<span id="266">266</span>
<span id="267">267</span>
<span id="268">268</span>
<span id="269">269</span>
<span id="270">270</span>
<span id="271">271</span>
<span id="272">272</span>
<span id="273">273</span>
<span id="274">274</span>
<span id="275">275</span>
<span id="276">276</span>
<span id="277">277</span>
<span id="278">278</span>
<span id="279">279</span>
<span id="280">280</span>
<span id="281">281</span>
<span id="282">282</span>
<span id="283">283</span>
<span id="284">284</span>
<span id="285">285</span>
<span id="286">286</span>
<span id="287">287</span>
<span id="288">288</span>
<span id="289">289</span>
<span id="290">290</span>
<span id="291">291</span>
<span id="292">292</span>
<span id="293">293</span>
<span id="294">294</span>
<span id="295">295</span>
<span id="296">296</span>
<span id="297">297</span>
<span id="298">298</span>
<span id="299">299</span>
<span id="300">300</span>
<span id="301">301</span>
<span id="302">302</span>
<span id="303">303</span>
<span id="304">304</span>
<span id="305">305</span>
<span id="306">306</span>
<span id="307">307</span>
<span id="308">308</span>
<span id="309">309</span>
<span id="310">310</span>
<span id="311">311</span>
<span id="312">312</span>
<span id="313">313</span>
<span id="314">314</span>
<span id="315">315</span>
<span id="316">316</span>
<span id="317">317</span>
<span id="318">318</span>
<span id="319">319</span>
<span id="320">320</span>
<span id="321">321</span>
<span id="322">322</span>
<span id="323">323</span>
<span id="324">324</span>
<span id="325">325</span>
<span id="326">326</span>
<span id="327">327</span>
<span id="328">328</span>
<span id="329">329</span>
<span id="330">330</span>
<span id="331">331</span>
<span id="332">332</span>
<span id="333">333</span>
<span id="334">334</span>
<span id="335">335</span>
<span id="336">336</span>
<span id="337">337</span>
<span id="338">338</span>
<span id="339">339</span>
<span id="340">340</span>
<span id="341">341</span>
<span id="342">342</span>
<span id="343">343</span>
<span id="344">344</span>
<span id="345">345</span>
<span id="346">346</span>
<span id="347">347</span>
<span id="348">348</span>
<span id="349">349</span>
<span id="350">350</span>
<span id="351">351</span>
<span id="352">352</span>
<span id="353">353</span>
<span id="354">354</span>
<span id="355">355</span>
<span id="356">356</span>
<span id="357">357</span>
<span id="358">358</span>
<span id="359">359</span>
<span id="360">360</span>
<span id="361">361</span>
</pre><pre class="rust"><code><span class="kw">use</span> <span class="ident">core::pin::Pin</span>;
<span class="kw">use</span> <span class="ident">std::net</span>::{<span class="ident">SocketAddr</span>, <span class="ident">ToSocketAddrs</span>};
<span class="kw">use</span> <span class="ident">std::time</span>::{<span class="ident">Duration</span>, <span class="ident">Instant</span>};
<span class="kw">use</span> <span class="ident">futures_util::sink::SinkExt</span>;
<span class="kw">use</span> <span class="ident">futures_util::stream::StreamExt</span>;
<span class="kw">use</span> <span class="ident">ldap3_proto::proto</span>::<span class="kw-2">*</span>;
<span class="kw">use</span> <span class="ident">ldap3_proto::LdapCodec</span>;
<span class="kw">use</span> <span class="ident">openssl::ssl</span>::{<span class="ident">Ssl</span>, <span class="ident">SslConnector</span>, <span class="ident">SslMethod</span>, <span class="ident">SslVerifyMode</span>};
<span class="comment">// use std::sync::atomic::{AtomicUsize, Ordering};</span>
<span class="kw">use</span> <span class="ident">tokio::net::TcpStream</span>;
<span class="kw">use</span> <span class="ident">tokio::sync::Mutex</span>;
<span class="kw">use</span> <span class="ident">tokio_openssl::SslStream</span>;
<span class="kw">use</span> <span class="ident">tokio_util::codec::Framed</span>;
<span class="kw">struct</span> <span class="ident">LdapInner</span> {
<span class="kw">pub</span> <span class="ident">framed</span>: <span class="ident">Framed</span><span class="op">&lt;</span><span class="ident">SslStream</span><span class="op">&lt;</span><span class="ident">TcpStream</span><span class="op">&gt;</span>, <span class="ident">LdapCodec</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">msgid</span>: <span class="ident">i32</span>,
}
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">LdapSchema</span> {
<span class="ident">Kanidm</span>,
<span class="ident">Rfc2307bis</span>,
}
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">LdapClient</span> {
<span class="kw">pub</span> <span class="ident">uri</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">addr</span>: <span class="ident">SocketAddr</span>,
<span class="kw">pub</span> <span class="ident">basedn</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">schema</span>: <span class="ident">LdapSchema</span>,
<span class="ident">conn</span>: <span class="ident">Mutex</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">LdapInner</span><span class="op">&gt;</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span> <span class="ident">std::fmt::Debug</span> <span class="kw">for</span> <span class="ident">LdapClient</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">std::fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">std::fmt::Result</span> {
<span class="ident">f</span>.<span class="ident">debug_struct</span>(<span class="string">&quot;LdapClient&quot;</span>)
.<span class="ident">field</span>(<span class="string">&quot;uri&quot;</span>, <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">uri</span>)
.<span class="ident">field</span>(<span class="string">&quot;addr&quot;</span>, <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">addr</span>)
.<span class="ident">finish</span>()
}
}
<span class="kw">impl</span> <span class="ident">LdapClient</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">uri</span>: <span class="ident">String</span>, <span class="ident">basedn</span>: <span class="ident">String</span>, <span class="ident">schema</span>: <span class="ident">LdapSchema</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="self">Self</span>, ()<span class="op">&gt;</span> {
<span class="comment">// Turn this into an address.</span>
<span class="macro">debug!</span>(<span class="string">&quot;ldap_uri {}&quot;</span>, <span class="ident">uri</span>);
<span class="comment">// First remove the ldaps from the start.</span>
<span class="kw">let</span> <span class="ident">trimmed</span> <span class="op">=</span> <span class="ident">uri</span>.<span class="ident">trim_start_matches</span>(<span class="string">&quot;ldaps://&quot;</span>);
<span class="comment">// Then provide the rest to the to_socket_addrs.</span>
<span class="kw">let</span> <span class="ident">addr</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">trimmed</span>.<span class="ident">to_socket_addrs</span>() {
<span class="prelude-val">Ok</span>(<span class="kw-2">mut</span> <span class="ident">addrs_iter</span>) =&gt; <span class="kw">match</span> <span class="ident">addrs_iter</span>.<span class="ident">next</span>() {
<span class="prelude-val">Some</span>(<span class="ident">addr</span>) =&gt; <span class="ident">addr</span>,
<span class="prelude-val">None</span> =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;No ldap uri addresses found&quot;</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
},
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Unable to parse LDAP uri address - {:?}&quot;</span>, <span class="ident">e</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
};
<span class="macro">debug!</span>(<span class="string">&quot;addr -&gt; {:?}&quot;</span>, <span class="ident">addr</span>);
<span class="comment">// now we store this for the tcp stream later.</span>
<span class="comment">// https://docs.rs/tokio/1.5.0/tokio/net/struct.TcpStream.html</span>
<span class="prelude-val">Ok</span>(<span class="ident">LdapClient</span> {
<span class="ident">uri</span>,
<span class="ident">addr</span>,
<span class="ident">basedn</span>,
<span class="ident">schema</span>,
<span class="ident">conn</span>: <span class="ident">Mutex::new</span>(<span class="prelude-val">None</span>),
})
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">bind</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">dn</span>: <span class="ident">String</span>, <span class="ident">pw</span>: <span class="ident">String</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">msg</span> <span class="op">=</span> <span class="ident">LdapMsg</span> {
<span class="ident">msgid</span>: <span class="number">1</span>,
<span class="ident">op</span>: <span class="ident">LdapOp::BindRequest</span>(<span class="ident">LdapBindRequest</span> {
<span class="ident">dn</span>,
<span class="ident">cred</span>: <span class="ident">LdapBindCred::Simple</span>(<span class="ident">pw</span>),
}),
<span class="ident">ctrl</span>: <span class="macro">vec!</span>[],
};
<span class="kw">let</span> <span class="ident">tcpstream</span> <span class="op">=</span> <span class="ident">TcpStream::connect</span>(<span class="self">self</span>.<span class="ident">addr</span>)
.<span class="kw">await</span>
.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="macro">error!</span>(<span class="string">&quot;Failed to connect to {} -&gt; {:?}&quot;</span>, <span class="self">self</span>.<span class="ident">uri</span>, <span class="ident">e</span>))<span class="question-mark">?</span>;
<span class="comment">// Now add TLS</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">tls_parms</span> <span class="op">=</span> <span class="ident">SslConnector::builder</span>(<span class="ident">SslMethod::tls_client</span>()).<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">error!</span>(<span class="string">&quot;openssl -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="ident">tls_parms</span>.<span class="ident">set_verify</span>(<span class="ident">SslVerifyMode::NONE</span>);
<span class="kw">let</span> <span class="ident">tls_parms</span> <span class="op">=</span> <span class="ident">tls_parms</span>.<span class="ident">build</span>();
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">tlsstream</span> <span class="op">=</span> <span class="ident">Ssl::new</span>(<span class="ident">tls_parms</span>.<span class="ident">context</span>())
.<span class="ident">and_then</span>(<span class="op">|</span><span class="ident">tls_obj</span><span class="op">|</span> <span class="ident">SslStream::new</span>(<span class="ident">tls_obj</span>, <span class="ident">tcpstream</span>))
.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">error!</span>(<span class="string">&quot;Failed to initialise TLS -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="ident">SslStream::connect</span>(<span class="ident">Pin::new</span>(<span class="kw-2">&amp;mut</span> <span class="ident">tlsstream</span>))
.<span class="kw">await</span>
.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">error!</span>(<span class="string">&quot;Failed to initialise TLS -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">framed</span> <span class="op">=</span> <span class="ident">Framed::new</span>(<span class="ident">tlsstream</span>, <span class="ident">LdapCodec</span>);
<span class="ident">framed</span>.<span class="ident">send</span>(<span class="ident">msg</span>).<span class="kw">await</span>.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">error!</span>(<span class="string">&quot;Unable to bind -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="prelude-val">Ok</span>(<span class="ident">msg</span>)) <span class="op">=</span> <span class="ident">framed</span>.<span class="ident">next</span>().<span class="kw">await</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="ident">LdapOp::BindResponse</span>(<span class="ident">res</span>) <span class="op">=</span> <span class="ident">msg</span>.<span class="ident">op</span> {
<span class="kw">if</span> <span class="ident">res</span>.<span class="ident">res</span>.<span class="ident">code</span> <span class="op">==</span> <span class="ident">LdapResultCode::Success</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">mguard</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">conn</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="kw-2">*</span><span class="ident">mguard</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">LdapInner</span> { <span class="ident">framed</span>, <span class="ident">msgid</span>: <span class="number">1</span> });
<span class="kw">return</span> <span class="prelude-val">Ok</span>(());
}
}
}
<span class="macro">error!</span>(<span class="string">&quot;Failed to bind&quot;</span>);
<span class="prelude-val">Err</span>(())
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">open_dm_connection</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">pw</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), ()<span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">bind</span>(<span class="string">&quot;cn=Directory Manager&quot;</span>.<span class="ident">to_string</span>(), <span class="ident">pw</span>.<span class="ident">to_string</span>())
.<span class="kw">await</span>
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">open_user_connection</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="ident">test_start</span>: <span class="ident">Instant</span>,
<span class="ident">name</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>,
<span class="ident">pw</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>,
) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(<span class="ident">Duration</span>, <span class="ident">Duration</span>), ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">dn</span> <span class="op">=</span> <span class="kw">match</span> <span class="self">self</span>.<span class="ident">schema</span> {
<span class="ident">LdapSchema::Kanidm</span> =&gt; <span class="ident">name</span>.<span class="ident">to_string</span>(),
<span class="ident">LdapSchema::Rfc2307bis</span> =&gt; <span class="macro">format!</span>(<span class="string">&quot;uid={},ou=people,{}&quot;</span>, <span class="ident">name</span>, <span class="self">self</span>.<span class="ident">basedn</span>),
};
<span class="kw">let</span> <span class="ident">start</span> <span class="op">=</span> <span class="ident">Instant::now</span>();
<span class="self">self</span>.<span class="ident">bind</span>(<span class="ident">dn</span>, <span class="ident">pw</span>.<span class="ident">to_string</span>()).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">end</span> <span class="op">=</span> <span class="ident">Instant::now</span>();
<span class="kw">let</span> <span class="ident">diff</span> <span class="op">=</span> <span class="ident">end</span>.<span class="ident">duration_since</span>(<span class="ident">start</span>);
<span class="kw">let</span> <span class="ident">rel_diff</span> <span class="op">=</span> <span class="ident">start</span>.<span class="ident">duration_since</span>(<span class="ident">test_start</span>);
<span class="prelude-val">Ok</span>((<span class="ident">rel_diff</span>, <span class="ident">diff</span>))
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">close_connection</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">mguard</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">conn</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="kw-2">*</span><span class="ident">mguard</span> <span class="op">=</span> <span class="prelude-val">None</span>;
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">search_name</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="ident">test_start</span>: <span class="ident">Instant</span>,
<span class="ident">ids</span>: <span class="kw-2">&amp;</span>[<span class="ident">String</span>],
) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(<span class="ident">Duration</span>, <span class="ident">Duration</span>, <span class="ident">usize</span>), ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">name_attr</span> <span class="op">=</span> <span class="kw">match</span> <span class="self">self</span>.<span class="ident">schema</span> {
<span class="ident">LdapSchema::Kanidm</span> =&gt; <span class="string">&quot;name&quot;</span>,
<span class="ident">LdapSchema::Rfc2307bis</span> =&gt; <span class="string">&quot;cn&quot;</span>,
};
<span class="kw">let</span> <span class="ident">filter</span> <span class="op">=</span> <span class="ident">LdapFilter::Or</span>(
<span class="ident">ids</span>.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">n</span><span class="op">|</span> <span class="ident">LdapFilter::Equality</span>(<span class="ident">name_attr</span>.<span class="ident">to_string</span>(), <span class="ident">n</span>.<span class="ident">to_string</span>()))
.<span class="ident">collect</span>(),
);
<span class="kw">let</span> <span class="ident">start</span> <span class="op">=</span> <span class="ident">Instant::now</span>();
<span class="kw">let</span> <span class="ident">res</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">search</span>(<span class="ident">filter</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">end</span> <span class="op">=</span> <span class="ident">Instant::now</span>();
<span class="kw">let</span> <span class="ident">diff</span> <span class="op">=</span> <span class="ident">end</span>.<span class="ident">duration_since</span>(<span class="ident">start</span>);
<span class="kw">let</span> <span class="ident">rel_diff</span> <span class="op">=</span> <span class="ident">start</span>.<span class="ident">duration_since</span>(<span class="ident">test_start</span>);
<span class="prelude-val">Ok</span>((<span class="ident">rel_diff</span>, <span class="ident">diff</span>, <span class="ident">res</span>.<span class="ident">len</span>()))
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">search</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">filter</span>: <span class="ident">LdapFilter</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">LdapSearchResultEntry</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="comment">// Create the search filter</span>
<span class="kw">let</span> <span class="ident">req</span> <span class="op">=</span> <span class="ident">LdapSearchRequest</span> {
<span class="ident">base</span>: <span class="self">self</span>.<span class="ident">basedn</span>.<span class="ident">clone</span>(),
<span class="ident">scope</span>: <span class="ident">LdapSearchScope::Subtree</span>,
<span class="ident">aliases</span>: <span class="ident">LdapDerefAliases::Never</span>,
<span class="ident">sizelimit</span>: <span class="number">0</span>,
<span class="ident">timelimit</span>: <span class="number">0</span>,
<span class="ident">typesonly</span>: <span class="bool-val">false</span>,
<span class="ident">filter</span>,
<span class="ident">attrs</span>: <span class="macro">vec!</span>[],
};
<span class="comment">// Prep the proto msg</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">mguard</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">conn</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="kw">match</span> (<span class="kw-2">*</span><span class="ident">mguard</span>).<span class="ident">as_mut</span>() {
<span class="prelude-val">Some</span>(<span class="ident">i</span>) =&gt; <span class="ident">i</span>,
<span class="prelude-val">None</span> =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;No connection available&quot;</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
};
<span class="ident">inner</span>.<span class="ident">msgid</span> <span class="op">+</span><span class="op">=</span> <span class="number">1</span>;
<span class="kw">let</span> <span class="ident">msgid</span> <span class="op">=</span> <span class="ident">inner</span>.<span class="ident">msgid</span>;
<span class="kw">let</span> <span class="ident">msg</span> <span class="op">=</span> <span class="ident">LdapMsg</span> {
<span class="ident">msgid</span>,
<span class="ident">ctrl</span>: <span class="macro">vec!</span>[],
<span class="ident">op</span>: <span class="ident">LdapOp::SearchRequest</span>(<span class="ident">req</span>),
};
<span class="comment">// Send it</span>
<span class="ident">inner</span>.<span class="ident">framed</span>.<span class="ident">send</span>(<span class="ident">msg</span>).<span class="kw">await</span>.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">error!</span>(<span class="string">&quot;Unable to search -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">results</span> <span class="op">=</span> <span class="ident">Vec::new</span>();
<span class="comment">// It takes a lot more work to process a response from ldap :(</span>
<span class="kw">while</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="prelude-val">Ok</span>(<span class="ident">msg</span>)) <span class="op">=</span> <span class="ident">inner</span>.<span class="ident">framed</span>.<span class="ident">next</span>().<span class="kw">await</span> {
<span class="kw">match</span> <span class="ident">msg</span>.<span class="ident">op</span> {
<span class="ident">LdapOp::SearchResultEntry</span>(<span class="ident">ent</span>) =&gt; <span class="ident">results</span>.<span class="ident">push</span>(<span class="ident">ent</span>),
<span class="ident">LdapOp::SearchResultDone</span>(<span class="ident">res</span>) =&gt; {
<span class="kw">if</span> <span class="ident">res</span>.<span class="ident">code</span> <span class="op">==</span> <span class="ident">LdapResultCode::Success</span> {
<span class="kw">break</span>;
} <span class="kw">else</span> {
<span class="macro">error!</span>(<span class="string">&quot;Search Failed -&gt; {:?}&quot;</span>, <span class="ident">res</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
}
<span class="kw">_</span> =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Invalid ldap response state&quot;</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
}
}
<span class="prelude-val">Ok</span>(<span class="ident">results</span>)
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">delete</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">dn</span>: <span class="ident">String</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">mguard</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">conn</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="kw">match</span> (<span class="kw-2">*</span><span class="ident">mguard</span>).<span class="ident">as_mut</span>() {
<span class="prelude-val">Some</span>(<span class="ident">i</span>) =&gt; <span class="ident">i</span>,
<span class="prelude-val">None</span> =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;No connection available&quot;</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
};
<span class="ident">inner</span>.<span class="ident">msgid</span> <span class="op">+</span><span class="op">=</span> <span class="number">1</span>;
<span class="kw">let</span> <span class="ident">msgid</span> <span class="op">=</span> <span class="ident">inner</span>.<span class="ident">msgid</span>;
<span class="kw">let</span> <span class="ident">msg</span> <span class="op">=</span> <span class="ident">LdapMsg</span> {
<span class="ident">msgid</span>,
<span class="ident">ctrl</span>: <span class="macro">vec!</span>[],
<span class="ident">op</span>: <span class="ident">LdapOp::DelRequest</span>(<span class="ident">dn</span>),
};
<span class="comment">// Send it</span>
<span class="ident">inner</span>.<span class="ident">framed</span>.<span class="ident">send</span>(<span class="ident">msg</span>).<span class="kw">await</span>.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">error!</span>(<span class="string">&quot;Unable to delete -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="prelude-val">Ok</span>(<span class="ident">msg</span>)) <span class="op">=</span> <span class="ident">inner</span>.<span class="ident">framed</span>.<span class="ident">next</span>().<span class="kw">await</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="ident">LdapOp::DelResponse</span>(<span class="ident">res</span>) <span class="op">=</span> <span class="ident">msg</span>.<span class="ident">op</span> {
<span class="kw">if</span> <span class="ident">res</span>.<span class="ident">code</span> <span class="op">==</span> <span class="ident">LdapResultCode::Success</span> {
<span class="kw">return</span> <span class="prelude-val">Ok</span>(());
} <span class="kw">else</span> {
<span class="macro">error!</span>(<span class="string">&quot;Delete Failed -&gt; {:?}&quot;</span>, <span class="ident">res</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
}
}
<span class="macro">error!</span>(<span class="string">&quot;Invalid ldap response state&quot;</span>);
<span class="prelude-val">Err</span>(())
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">add</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">req</span>: <span class="ident">LdapAddRequest</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">mguard</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">conn</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="kw">match</span> (<span class="kw-2">*</span><span class="ident">mguard</span>).<span class="ident">as_mut</span>() {
<span class="prelude-val">Some</span>(<span class="ident">i</span>) =&gt; <span class="ident">i</span>,
<span class="prelude-val">None</span> =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;No connection available&quot;</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
};
<span class="ident">inner</span>.<span class="ident">msgid</span> <span class="op">+</span><span class="op">=</span> <span class="number">1</span>;
<span class="kw">let</span> <span class="ident">msgid</span> <span class="op">=</span> <span class="ident">inner</span>.<span class="ident">msgid</span>;
<span class="kw">let</span> <span class="ident">msg</span> <span class="op">=</span> <span class="ident">LdapMsg</span> {
<span class="ident">msgid</span>,
<span class="ident">ctrl</span>: <span class="macro">vec!</span>[],
<span class="ident">op</span>: <span class="ident">LdapOp::AddRequest</span>(<span class="ident">req</span>),
};
<span class="comment">// Send it</span>
<span class="ident">inner</span>.<span class="ident">framed</span>.<span class="ident">send</span>(<span class="ident">msg</span>).<span class="kw">await</span>.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">error!</span>(<span class="string">&quot;Unable to add -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="prelude-val">Ok</span>(<span class="ident">msg</span>)) <span class="op">=</span> <span class="ident">inner</span>.<span class="ident">framed</span>.<span class="ident">next</span>().<span class="kw">await</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="ident">LdapOp::AddResponse</span>(<span class="ident">res</span>) <span class="op">=</span> <span class="ident">msg</span>.<span class="ident">op</span> {
<span class="kw">if</span> <span class="ident">res</span>.<span class="ident">code</span> <span class="op">==</span> <span class="ident">LdapResultCode::Success</span> {
<span class="kw">return</span> <span class="prelude-val">Ok</span>(());
} <span class="kw">else</span> {
<span class="macro">error!</span>(<span class="string">&quot;Add Failed -&gt; {:?}&quot;</span>, <span class="ident">res</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
}
}
<span class="macro">error!</span>(<span class="string">&quot;Invalid ldap response state&quot;</span>);
<span class="prelude-val">Err</span>(())
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">modify</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">req</span>: <span class="ident">LdapModifyRequest</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">mguard</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">conn</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="kw">match</span> (<span class="kw-2">*</span><span class="ident">mguard</span>).<span class="ident">as_mut</span>() {
<span class="prelude-val">Some</span>(<span class="ident">i</span>) =&gt; <span class="ident">i</span>,
<span class="prelude-val">None</span> =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;No connection available&quot;</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
};
<span class="ident">inner</span>.<span class="ident">msgid</span> <span class="op">+</span><span class="op">=</span> <span class="number">1</span>;
<span class="kw">let</span> <span class="ident">msgid</span> <span class="op">=</span> <span class="ident">inner</span>.<span class="ident">msgid</span>;
<span class="kw">let</span> <span class="ident">msg</span> <span class="op">=</span> <span class="ident">LdapMsg</span> {
<span class="ident">msgid</span>,
<span class="ident">ctrl</span>: <span class="macro">vec!</span>[],
<span class="ident">op</span>: <span class="ident">LdapOp::ModifyRequest</span>(<span class="ident">req</span>),
};
<span class="comment">// Send it</span>
<span class="ident">inner</span>.<span class="ident">framed</span>.<span class="ident">send</span>(<span class="ident">msg</span>).<span class="kw">await</span>.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">error!</span>(<span class="string">&quot;Unable to modify -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="prelude-val">Ok</span>(<span class="ident">msg</span>)) <span class="op">=</span> <span class="ident">inner</span>.<span class="ident">framed</span>.<span class="ident">next</span>().<span class="kw">await</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="ident">LdapOp::ModifyResponse</span>(<span class="ident">res</span>) <span class="op">=</span> <span class="ident">msg</span>.<span class="ident">op</span> {
<span class="kw">if</span> <span class="ident">res</span>.<span class="ident">code</span> <span class="op">==</span> <span class="ident">LdapResultCode::Success</span> {
<span class="kw">return</span> <span class="prelude-val">Ok</span>(());
} <span class="kw">else</span> {
<span class="macro">error!</span>(<span class="string">&quot;Modify Failed -&gt; {:?}&quot;</span>, <span class="ident">res</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
}
}
}
<span class="macro">error!</span>(<span class="string">&quot;Invalid ldap response state&quot;</span>);
<span class="prelude-val">Err</span>(())
}
}
</code></pre></div>
</section></div></main><div id="rustdoc-vars" data-root-path="../../" data-current-crate="orca" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.64.0 (a55dd71d5 2022-09-19)" ></div></body></html>