kanidm/docs/v1.0.0-rc10/rustdoc/src/kanidm_unix_common/cache.rs.html
2022-05-22 22:26:40 +00:00

1944 lines
131 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 `kanidm_unix_int/src/cache.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>cache.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 src="../../crates.js"></script><script defer src="../../main.js"></script><script defer src="../../source-script.js"></script><script defer src="../../source-files.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="../../kanidm_unix_common/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="../../kanidm_unix_common/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="../../kanidm_unix_common/index.html"><img class="rust-logo" src="../../rust-logo.svg" alt="logo"></a><nav class="sub"><div class="theme-picker hidden"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu" title="themes"><img width="22" height="22" alt="Pick another theme!" src="../../brush.svg"></button><div id="theme-choices" role="menu"></div></div><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"><button type="button" id="help-button" title="help">?</button><a id="settings-menu" href="../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../wheel.svg"></a></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>
<span id="362">362</span>
<span id="363">363</span>
<span id="364">364</span>
<span id="365">365</span>
<span id="366">366</span>
<span id="367">367</span>
<span id="368">368</span>
<span id="369">369</span>
<span id="370">370</span>
<span id="371">371</span>
<span id="372">372</span>
<span id="373">373</span>
<span id="374">374</span>
<span id="375">375</span>
<span id="376">376</span>
<span id="377">377</span>
<span id="378">378</span>
<span id="379">379</span>
<span id="380">380</span>
<span id="381">381</span>
<span id="382">382</span>
<span id="383">383</span>
<span id="384">384</span>
<span id="385">385</span>
<span id="386">386</span>
<span id="387">387</span>
<span id="388">388</span>
<span id="389">389</span>
<span id="390">390</span>
<span id="391">391</span>
<span id="392">392</span>
<span id="393">393</span>
<span id="394">394</span>
<span id="395">395</span>
<span id="396">396</span>
<span id="397">397</span>
<span id="398">398</span>
<span id="399">399</span>
<span id="400">400</span>
<span id="401">401</span>
<span id="402">402</span>
<span id="403">403</span>
<span id="404">404</span>
<span id="405">405</span>
<span id="406">406</span>
<span id="407">407</span>
<span id="408">408</span>
<span id="409">409</span>
<span id="410">410</span>
<span id="411">411</span>
<span id="412">412</span>
<span id="413">413</span>
<span id="414">414</span>
<span id="415">415</span>
<span id="416">416</span>
<span id="417">417</span>
<span id="418">418</span>
<span id="419">419</span>
<span id="420">420</span>
<span id="421">421</span>
<span id="422">422</span>
<span id="423">423</span>
<span id="424">424</span>
<span id="425">425</span>
<span id="426">426</span>
<span id="427">427</span>
<span id="428">428</span>
<span id="429">429</span>
<span id="430">430</span>
<span id="431">431</span>
<span id="432">432</span>
<span id="433">433</span>
<span id="434">434</span>
<span id="435">435</span>
<span id="436">436</span>
<span id="437">437</span>
<span id="438">438</span>
<span id="439">439</span>
<span id="440">440</span>
<span id="441">441</span>
<span id="442">442</span>
<span id="443">443</span>
<span id="444">444</span>
<span id="445">445</span>
<span id="446">446</span>
<span id="447">447</span>
<span id="448">448</span>
<span id="449">449</span>
<span id="450">450</span>
<span id="451">451</span>
<span id="452">452</span>
<span id="453">453</span>
<span id="454">454</span>
<span id="455">455</span>
<span id="456">456</span>
<span id="457">457</span>
<span id="458">458</span>
<span id="459">459</span>
<span id="460">460</span>
<span id="461">461</span>
<span id="462">462</span>
<span id="463">463</span>
<span id="464">464</span>
<span id="465">465</span>
<span id="466">466</span>
<span id="467">467</span>
<span id="468">468</span>
<span id="469">469</span>
<span id="470">470</span>
<span id="471">471</span>
<span id="472">472</span>
<span id="473">473</span>
<span id="474">474</span>
<span id="475">475</span>
<span id="476">476</span>
<span id="477">477</span>
<span id="478">478</span>
<span id="479">479</span>
<span id="480">480</span>
<span id="481">481</span>
<span id="482">482</span>
<span id="483">483</span>
<span id="484">484</span>
<span id="485">485</span>
<span id="486">486</span>
<span id="487">487</span>
<span id="488">488</span>
<span id="489">489</span>
<span id="490">490</span>
<span id="491">491</span>
<span id="492">492</span>
<span id="493">493</span>
<span id="494">494</span>
<span id="495">495</span>
<span id="496">496</span>
<span id="497">497</span>
<span id="498">498</span>
<span id="499">499</span>
<span id="500">500</span>
<span id="501">501</span>
<span id="502">502</span>
<span id="503">503</span>
<span id="504">504</span>
<span id="505">505</span>
<span id="506">506</span>
<span id="507">507</span>
<span id="508">508</span>
<span id="509">509</span>
<span id="510">510</span>
<span id="511">511</span>
<span id="512">512</span>
<span id="513">513</span>
<span id="514">514</span>
<span id="515">515</span>
<span id="516">516</span>
<span id="517">517</span>
<span id="518">518</span>
<span id="519">519</span>
<span id="520">520</span>
<span id="521">521</span>
<span id="522">522</span>
<span id="523">523</span>
<span id="524">524</span>
<span id="525">525</span>
<span id="526">526</span>
<span id="527">527</span>
<span id="528">528</span>
<span id="529">529</span>
<span id="530">530</span>
<span id="531">531</span>
<span id="532">532</span>
<span id="533">533</span>
<span id="534">534</span>
<span id="535">535</span>
<span id="536">536</span>
<span id="537">537</span>
<span id="538">538</span>
<span id="539">539</span>
<span id="540">540</span>
<span id="541">541</span>
<span id="542">542</span>
<span id="543">543</span>
<span id="544">544</span>
<span id="545">545</span>
<span id="546">546</span>
<span id="547">547</span>
<span id="548">548</span>
<span id="549">549</span>
<span id="550">550</span>
<span id="551">551</span>
<span id="552">552</span>
<span id="553">553</span>
<span id="554">554</span>
<span id="555">555</span>
<span id="556">556</span>
<span id="557">557</span>
<span id="558">558</span>
<span id="559">559</span>
<span id="560">560</span>
<span id="561">561</span>
<span id="562">562</span>
<span id="563">563</span>
<span id="564">564</span>
<span id="565">565</span>
<span id="566">566</span>
<span id="567">567</span>
<span id="568">568</span>
<span id="569">569</span>
<span id="570">570</span>
<span id="571">571</span>
<span id="572">572</span>
<span id="573">573</span>
<span id="574">574</span>
<span id="575">575</span>
<span id="576">576</span>
<span id="577">577</span>
<span id="578">578</span>
<span id="579">579</span>
<span id="580">580</span>
<span id="581">581</span>
<span id="582">582</span>
<span id="583">583</span>
<span id="584">584</span>
<span id="585">585</span>
<span id="586">586</span>
<span id="587">587</span>
<span id="588">588</span>
<span id="589">589</span>
<span id="590">590</span>
<span id="591">591</span>
<span id="592">592</span>
<span id="593">593</span>
<span id="594">594</span>
<span id="595">595</span>
<span id="596">596</span>
<span id="597">597</span>
<span id="598">598</span>
<span id="599">599</span>
<span id="600">600</span>
<span id="601">601</span>
<span id="602">602</span>
<span id="603">603</span>
<span id="604">604</span>
<span id="605">605</span>
<span id="606">606</span>
<span id="607">607</span>
<span id="608">608</span>
<span id="609">609</span>
<span id="610">610</span>
<span id="611">611</span>
<span id="612">612</span>
<span id="613">613</span>
<span id="614">614</span>
<span id="615">615</span>
<span id="616">616</span>
<span id="617">617</span>
<span id="618">618</span>
<span id="619">619</span>
<span id="620">620</span>
<span id="621">621</span>
<span id="622">622</span>
<span id="623">623</span>
<span id="624">624</span>
<span id="625">625</span>
<span id="626">626</span>
<span id="627">627</span>
<span id="628">628</span>
<span id="629">629</span>
<span id="630">630</span>
<span id="631">631</span>
<span id="632">632</span>
<span id="633">633</span>
<span id="634">634</span>
<span id="635">635</span>
<span id="636">636</span>
<span id="637">637</span>
<span id="638">638</span>
<span id="639">639</span>
<span id="640">640</span>
<span id="641">641</span>
<span id="642">642</span>
<span id="643">643</span>
<span id="644">644</span>
<span id="645">645</span>
<span id="646">646</span>
<span id="647">647</span>
<span id="648">648</span>
<span id="649">649</span>
<span id="650">650</span>
<span id="651">651</span>
<span id="652">652</span>
<span id="653">653</span>
<span id="654">654</span>
<span id="655">655</span>
<span id="656">656</span>
<span id="657">657</span>
<span id="658">658</span>
<span id="659">659</span>
<span id="660">660</span>
<span id="661">661</span>
<span id="662">662</span>
<span id="663">663</span>
<span id="664">664</span>
<span id="665">665</span>
<span id="666">666</span>
<span id="667">667</span>
<span id="668">668</span>
<span id="669">669</span>
<span id="670">670</span>
<span id="671">671</span>
<span id="672">672</span>
<span id="673">673</span>
<span id="674">674</span>
<span id="675">675</span>
<span id="676">676</span>
<span id="677">677</span>
<span id="678">678</span>
<span id="679">679</span>
<span id="680">680</span>
<span id="681">681</span>
<span id="682">682</span>
<span id="683">683</span>
<span id="684">684</span>
<span id="685">685</span>
<span id="686">686</span>
<span id="687">687</span>
<span id="688">688</span>
<span id="689">689</span>
<span id="690">690</span>
<span id="691">691</span>
<span id="692">692</span>
<span id="693">693</span>
<span id="694">694</span>
<span id="695">695</span>
<span id="696">696</span>
<span id="697">697</span>
<span id="698">698</span>
<span id="699">699</span>
<span id="700">700</span>
<span id="701">701</span>
<span id="702">702</span>
<span id="703">703</span>
<span id="704">704</span>
<span id="705">705</span>
<span id="706">706</span>
<span id="707">707</span>
<span id="708">708</span>
<span id="709">709</span>
<span id="710">710</span>
<span id="711">711</span>
<span id="712">712</span>
<span id="713">713</span>
<span id="714">714</span>
<span id="715">715</span>
<span id="716">716</span>
<span id="717">717</span>
<span id="718">718</span>
<span id="719">719</span>
<span id="720">720</span>
<span id="721">721</span>
<span id="722">722</span>
<span id="723">723</span>
<span id="724">724</span>
<span id="725">725</span>
<span id="726">726</span>
<span id="727">727</span>
<span id="728">728</span>
<span id="729">729</span>
<span id="730">730</span>
<span id="731">731</span>
<span id="732">732</span>
<span id="733">733</span>
<span id="734">734</span>
<span id="735">735</span>
<span id="736">736</span>
<span id="737">737</span>
<span id="738">738</span>
<span id="739">739</span>
<span id="740">740</span>
<span id="741">741</span>
<span id="742">742</span>
<span id="743">743</span>
<span id="744">744</span>
<span id="745">745</span>
<span id="746">746</span>
<span id="747">747</span>
<span id="748">748</span>
<span id="749">749</span>
<span id="750">750</span>
<span id="751">751</span>
<span id="752">752</span>
<span id="753">753</span>
<span id="754">754</span>
<span id="755">755</span>
<span id="756">756</span>
<span id="757">757</span>
<span id="758">758</span>
<span id="759">759</span>
<span id="760">760</span>
<span id="761">761</span>
<span id="762">762</span>
<span id="763">763</span>
<span id="764">764</span>
<span id="765">765</span>
<span id="766">766</span>
<span id="767">767</span>
<span id="768">768</span>
<span id="769">769</span>
<span id="770">770</span>
<span id="771">771</span>
<span id="772">772</span>
<span id="773">773</span>
<span id="774">774</span>
<span id="775">775</span>
<span id="776">776</span>
<span id="777">777</span>
<span id="778">778</span>
<span id="779">779</span>
<span id="780">780</span>
<span id="781">781</span>
<span id="782">782</span>
<span id="783">783</span>
<span id="784">784</span>
<span id="785">785</span>
<span id="786">786</span>
<span id="787">787</span>
<span id="788">788</span>
<span id="789">789</span>
<span id="790">790</span>
<span id="791">791</span>
<span id="792">792</span>
<span id="793">793</span>
<span id="794">794</span>
<span id="795">795</span>
<span id="796">796</span>
<span id="797">797</span>
<span id="798">798</span>
<span id="799">799</span>
<span id="800">800</span>
<span id="801">801</span>
<span id="802">802</span>
<span id="803">803</span>
<span id="804">804</span>
<span id="805">805</span>
<span id="806">806</span>
<span id="807">807</span>
<span id="808">808</span>
<span id="809">809</span>
<span id="810">810</span>
<span id="811">811</span>
<span id="812">812</span>
<span id="813">813</span>
<span id="814">814</span>
<span id="815">815</span>
<span id="816">816</span>
<span id="817">817</span>
<span id="818">818</span>
<span id="819">819</span>
<span id="820">820</span>
<span id="821">821</span>
<span id="822">822</span>
<span id="823">823</span>
<span id="824">824</span>
<span id="825">825</span>
<span id="826">826</span>
<span id="827">827</span>
<span id="828">828</span>
<span id="829">829</span>
<span id="830">830</span>
<span id="831">831</span>
<span id="832">832</span>
<span id="833">833</span>
<span id="834">834</span>
<span id="835">835</span>
<span id="836">836</span>
<span id="837">837</span>
<span id="838">838</span>
<span id="839">839</span>
<span id="840">840</span>
<span id="841">841</span>
<span id="842">842</span>
<span id="843">843</span>
<span id="844">844</span>
<span id="845">845</span>
<span id="846">846</span>
<span id="847">847</span>
<span id="848">848</span>
<span id="849">849</span>
<span id="850">850</span>
<span id="851">851</span>
<span id="852">852</span>
<span id="853">853</span>
<span id="854">854</span>
<span id="855">855</span>
<span id="856">856</span>
<span id="857">857</span>
<span id="858">858</span>
<span id="859">859</span>
<span id="860">860</span>
<span id="861">861</span>
<span id="862">862</span>
<span id="863">863</span>
<span id="864">864</span>
<span id="865">865</span>
<span id="866">866</span>
<span id="867">867</span>
<span id="868">868</span>
<span id="869">869</span>
<span id="870">870</span>
<span id="871">871</span>
<span id="872">872</span>
<span id="873">873</span>
<span id="874">874</span>
<span id="875">875</span>
<span id="876">876</span>
<span id="877">877</span>
<span id="878">878</span>
<span id="879">879</span>
<span id="880">880</span>
<span id="881">881</span>
<span id="882">882</span>
<span id="883">883</span>
<span id="884">884</span>
<span id="885">885</span>
<span id="886">886</span>
<span id="887">887</span>
<span id="888">888</span>
<span id="889">889</span>
<span id="890">890</span>
<span id="891">891</span>
<span id="892">892</span>
<span id="893">893</span>
<span id="894">894</span>
<span id="895">895</span>
<span id="896">896</span>
<span id="897">897</span>
<span id="898">898</span>
<span id="899">899</span>
<span id="900">900</span>
<span id="901">901</span>
<span id="902">902</span>
<span id="903">903</span>
<span id="904">904</span>
<span id="905">905</span>
<span id="906">906</span>
<span id="907">907</span>
<span id="908">908</span>
<span id="909">909</span>
<span id="910">910</span>
<span id="911">911</span>
<span id="912">912</span>
<span id="913">913</span>
<span id="914">914</span>
<span id="915">915</span>
<span id="916">916</span>
<span id="917">917</span>
<span id="918">918</span>
<span id="919">919</span>
<span id="920">920</span>
<span id="921">921</span>
<span id="922">922</span>
<span id="923">923</span>
<span id="924">924</span>
<span id="925">925</span>
<span id="926">926</span>
<span id="927">927</span>
<span id="928">928</span>
<span id="929">929</span>
<span id="930">930</span>
<span id="931">931</span>
<span id="932">932</span>
<span id="933">933</span>
<span id="934">934</span>
<span id="935">935</span>
<span id="936">936</span>
<span id="937">937</span>
<span id="938">938</span>
<span id="939">939</span>
<span id="940">940</span>
<span id="941">941</span>
<span id="942">942</span>
<span id="943">943</span>
<span id="944">944</span>
<span id="945">945</span>
<span id="946">946</span>
<span id="947">947</span>
<span id="948">948</span>
<span id="949">949</span>
<span id="950">950</span>
<span id="951">951</span>
<span id="952">952</span>
<span id="953">953</span>
<span id="954">954</span>
<span id="955">955</span>
<span id="956">956</span>
<span id="957">957</span>
<span id="958">958</span>
<span id="959">959</span>
<span id="960">960</span>
<span id="961">961</span>
<span id="962">962</span>
<span id="963">963</span>
<span id="964">964</span>
<span id="965">965</span>
<span id="966">966</span>
<span id="967">967</span>
<span id="968">968</span>
</pre><pre class="rust"><code><span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::db::Db</span>;
<span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::unix_config</span>::{<span class="ident">HomeAttr</span>, <span class="ident">UidAttr</span>};
<span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::unix_proto</span>::{<span class="ident">HomeDirectoryInfo</span>, <span class="ident">NssGroup</span>, <span class="ident">NssUser</span>};
<span class="kw">use</span> <span class="ident">kanidm_client::ClientError</span>;
<span class="kw">use</span> <span class="ident">kanidm_client::KanidmClient</span>;
<span class="kw">use</span> <span class="ident">kanidm_proto::v1</span>::{<span class="ident">OperationError</span>, <span class="ident">UnixGroupToken</span>, <span class="ident">UnixUserToken</span>};
<span class="kw">use</span> <span class="ident">lru::LruCache</span>;
<span class="kw">use</span> <span class="ident">reqwest::StatusCode</span>;
<span class="kw">use</span> <span class="ident">std::collections::BTreeSet</span>;
<span class="kw">use</span> <span class="ident">std::ops</span>::{<span class="ident">Add</span>, <span class="ident">Sub</span>};
<span class="kw">use</span> <span class="ident">std::path::Path</span>;
<span class="kw">use</span> <span class="ident">std::string::ToString</span>;
<span class="kw">use</span> <span class="ident">std::time</span>::{<span class="ident">Duration</span>, <span class="ident">SystemTime</span>};
<span class="kw">use</span> <span class="ident">tokio::sync</span>::{<span class="ident">Mutex</span>, <span class="ident">RwLock</span>};
<span class="kw">const</span> <span class="ident">NXCACHE_SIZE</span>: <span class="ident">usize</span> <span class="op">=</span> <span class="number">2048</span>;
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Clone</span>, <span class="ident">PartialEq</span>, <span class="ident">Eq</span>, <span class="ident">Hash</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">Id</span> {
<span class="ident">Name</span>(<span class="ident">String</span>),
<span class="ident">Gid</span>(<span class="ident">u32</span>),
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">enum</span> <span class="ident">CacheState</span> {
<span class="ident">Online</span>,
<span class="ident">Offline</span>,
<span class="ident">OfflineNextCheck</span>(<span class="ident">SystemTime</span>),
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">CacheLayer</span> {
<span class="ident">db</span>: <span class="ident">Db</span>,
<span class="ident">client</span>: <span class="ident">RwLock</span><span class="op">&lt;</span><span class="ident">KanidmClient</span><span class="op">&gt;</span>,
<span class="ident">state</span>: <span class="ident">Mutex</span><span class="op">&lt;</span><span class="ident">CacheState</span><span class="op">&gt;</span>,
<span class="ident">pam_allow_groups</span>: <span class="ident">BTreeSet</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
<span class="ident">timeout_seconds</span>: <span class="ident">u64</span>,
<span class="ident">default_shell</span>: <span class="ident">String</span>,
<span class="ident">home_prefix</span>: <span class="ident">String</span>,
<span class="ident">home_attr</span>: <span class="ident">HomeAttr</span>,
<span class="ident">home_alias</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">HomeAttr</span><span class="op">&gt;</span>,
<span class="ident">uid_attr_map</span>: <span class="ident">UidAttr</span>,
<span class="ident">gid_attr_map</span>: <span class="ident">UidAttr</span>,
<span class="ident">nxcache</span>: <span class="ident">Mutex</span><span class="op">&lt;</span><span class="ident">LruCache</span><span class="op">&lt;</span><span class="ident">Id</span>, <span class="ident">SystemTime</span><span class="op">&gt;</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span> <span class="ident">ToString</span> <span class="kw">for</span> <span class="ident">Id</span> {
<span class="kw">fn</span> <span class="ident">to_string</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="ident">String</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">Id::Name</span>(<span class="ident">s</span>) =&gt; <span class="ident">s</span>.<span class="ident">clone</span>(),
<span class="ident">Id::Gid</span>(<span class="ident">g</span>) =&gt; <span class="ident">g</span>.<span class="ident">to_string</span>(),
}
}
}
<span class="kw">impl</span> <span class="ident">CacheLayer</span> {
<span class="comment">// TODO: Could consider refactoring this to be better ...</span>
<span class="attribute">#[<span class="ident">allow</span>(<span class="ident">clippy::too_many_arguments</span>)]</span>
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">new</span>(
<span class="comment">// need db path</span>
<span class="ident">path</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>,
<span class="comment">// cache timeout</span>
<span class="ident">timeout_seconds</span>: <span class="ident">u64</span>,
<span class="comment">//</span>
<span class="ident">client</span>: <span class="ident">KanidmClient</span>,
<span class="ident">pam_allow_groups</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
<span class="ident">default_shell</span>: <span class="ident">String</span>,
<span class="ident">home_prefix</span>: <span class="ident">String</span>,
<span class="ident">home_attr</span>: <span class="ident">HomeAttr</span>,
<span class="ident">home_alias</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">HomeAttr</span><span class="op">&gt;</span>,
<span class="ident">uid_attr_map</span>: <span class="ident">UidAttr</span>,
<span class="ident">gid_attr_map</span>: <span class="ident">UidAttr</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="kw">let</span> <span class="ident">db</span> <span class="op">=</span> <span class="ident">Db::new</span>(<span class="ident">path</span>)<span class="question-mark">?</span>;
<span class="comment">// setup and do a migrate.</span>
{
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>.<span class="ident">migrate</span>()<span class="question-mark">?</span>;
<span class="ident">dbtxn</span>.<span class="ident">commit</span>()<span class="question-mark">?</span>;
}
<span class="kw">if</span> <span class="ident">pam_allow_groups</span>.<span class="ident">len</span>() <span class="op">==</span> <span class="number">0</span> {
<span class="macro">eprintln!</span>(<span class="string">&quot;Will not be able to authenticate users, pam_allow_groups config is not configured.&quot;</span>);
}
<span class="comment">// We assume we are offline at start up, and we mark the next &quot;online check&quot; as</span>
<span class="comment">// being valid from &quot;now&quot;.</span>
<span class="prelude-val">Ok</span>(<span class="ident">CacheLayer</span> {
<span class="ident">db</span>,
<span class="ident">client</span>: <span class="ident">RwLock::new</span>(<span class="ident">client</span>),
<span class="ident">state</span>: <span class="ident">Mutex::new</span>(<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">SystemTime::now</span>())),
<span class="ident">timeout_seconds</span>,
<span class="ident">pam_allow_groups</span>: <span class="ident">pam_allow_groups</span>.<span class="ident">into_iter</span>().<span class="ident">collect</span>(),
<span class="ident">default_shell</span>,
<span class="ident">home_prefix</span>,
<span class="ident">home_attr</span>,
<span class="ident">home_alias</span>,
<span class="ident">uid_attr_map</span>,
<span class="ident">gid_attr_map</span>,
<span class="ident">nxcache</span>: <span class="ident">Mutex::new</span>(<span class="ident">LruCache::new</span>(<span class="ident">NXCACHE_SIZE</span>)),
})
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_cachestate</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="ident">CacheState</span> {
<span class="kw">let</span> <span class="ident">g</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">state</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
(<span class="kw-2">*</span><span class="ident">g</span>).<span class="ident">clone</span>()
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">set_cachestate</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">state</span>: <span class="ident">CacheState</span>) {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">g</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">state</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="kw-2">*</span><span class="ident">g</span> <span class="op">=</span> <span class="ident">state</span>;
}
<span class="comment">// Need a way to mark online/offline.</span>
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">attempt_online</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="self">self</span>.<span class="ident">set_cachestate</span>(<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">SystemTime::now</span>()))
.<span class="kw">await</span>;
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">mark_offline</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="self">self</span>.<span class="ident">set_cachestate</span>(<span class="ident">CacheState::Offline</span>).<span class="kw">await</span>;
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">clear_cache</span>(<span class="kw-2">&amp;</span><span class="self">self</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">nxcache_txn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">nxcache</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="ident">nxcache_txn</span>.<span class="ident">clear</span>();
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>.<span class="ident">clear_cache</span>().<span class="ident">and_then</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="ident">dbtxn</span>.<span class="ident">commit</span>())
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">invalidate</span>(<span class="kw-2">&amp;</span><span class="self">self</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">nxcache_txn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">nxcache</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="ident">nxcache_txn</span>.<span class="ident">clear</span>();
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>.<span class="ident">invalidate</span>().<span class="ident">and_then</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="ident">dbtxn</span>.<span class="ident">commit</span>())
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_cached_usertokens</span>(<span class="kw-2">&amp;</span><span class="self">self</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">UnixUserToken</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>.<span class="ident">get_accounts</span>()
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_cached_grouptokens</span>(<span class="kw-2">&amp;</span><span class="self">self</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">UnixGroupToken</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>.<span class="ident">get_groups</span>()
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">set_nxcache</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">id</span>: <span class="kw-2">&amp;</span><span class="ident">Id</span>) {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">nxcache_txn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">nxcache</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">ex_time</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>() <span class="op">+</span> <span class="ident">Duration::from_secs</span>(<span class="self">self</span>.<span class="ident">timeout_seconds</span>);
<span class="ident">nxcache_txn</span>.<span class="ident">put</span>(<span class="ident">id</span>.<span class="ident">clone</span>(), <span class="ident">ex_time</span>);
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">check_nxcache</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">id</span>: <span class="kw-2">&amp;</span><span class="ident">Id</span>) -&gt; <span class="ident">bool</span> {
<span class="kw">let</span> <span class="ident">nxcache_txn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">nxcache</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="ident">nxcache_txn</span>.<span class="ident">contains</span>(<span class="ident">id</span>)
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_cached_usertoken</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="ident">account_id</span>: <span class="kw-2">&amp;</span><span class="ident">Id</span>,
) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(<span class="ident">bool</span>, <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnixUserToken</span><span class="op">&gt;</span>), ()<span class="op">&gt;</span> {
<span class="comment">// Account_id could be:</span>
<span class="comment">// * gidnumber</span>
<span class="comment">// * name</span>
<span class="comment">// * spn</span>
<span class="comment">// * uuid</span>
<span class="comment">// Attempt to search these in the db.</span>
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">r</span> <span class="op">=</span> <span class="ident">dbtxn</span>.<span class="ident">get_account</span>(<span class="kw-2">&amp;</span><span class="ident">account_id</span>)<span class="question-mark">?</span>;
<span class="kw">match</span> <span class="ident">r</span> {
<span class="prelude-val">Some</span>((<span class="ident">ut</span>, <span class="ident">ex</span>)) =&gt; {
<span class="comment">// Are we expired?</span>
<span class="kw">let</span> <span class="ident">offset</span> <span class="op">=</span> <span class="ident">Duration::from_secs</span>(<span class="ident">ex</span>);
<span class="kw">let</span> <span class="ident">ex_time</span> <span class="op">=</span> <span class="ident">SystemTime::UNIX_EPOCH</span> <span class="op">+</span> <span class="ident">offset</span>;
<span class="kw">let</span> <span class="ident">now</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>();
<span class="kw">if</span> <span class="ident">now</span> <span class="op">&gt;</span><span class="op">=</span> <span class="ident">ex_time</span> {
<span class="prelude-val">Ok</span>((<span class="bool-val">true</span>, <span class="prelude-val">Some</span>(<span class="ident">ut</span>)))
} <span class="kw">else</span> {
<span class="prelude-val">Ok</span>((<span class="bool-val">false</span>, <span class="prelude-val">Some</span>(<span class="ident">ut</span>)))
}
}
<span class="prelude-val">None</span> =&gt; {
<span class="comment">// it wasn&#39;t in the DB - lets see if it&#39;s in the nxcache.</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">nxcache_txn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">nxcache</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">nxcache_txn</span>.<span class="ident">get</span>(<span class="ident">account_id</span>) {
<span class="prelude-val">Some</span>(<span class="ident">ex_time</span>) =&gt; {
<span class="kw">let</span> <span class="ident">now</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>();
<span class="kw">if</span> <span class="kw-2">&amp;</span><span class="ident">now</span> <span class="op">&gt;</span><span class="op">=</span> <span class="ident">ex_time</span> {
<span class="comment">// It&#39;s in the LRU, but we are past the expiry so</span>
<span class="comment">// lets attempt a refresh.</span>
<span class="prelude-val">Ok</span>((<span class="bool-val">true</span>, <span class="prelude-val">None</span>))
} <span class="kw">else</span> {
<span class="comment">// It&#39;s in the LRU and still valid, so return that</span>
<span class="comment">// no check is needed.</span>
<span class="prelude-val">Ok</span>((<span class="bool-val">false</span>, <span class="prelude-val">None</span>))
}
}
<span class="prelude-val">None</span> =&gt; {
<span class="comment">// Not in the LRU. Return that this IS expired</span>
<span class="comment">// and we have no data.</span>
<span class="prelude-val">Ok</span>((<span class="bool-val">true</span>, <span class="prelude-val">None</span>))
}
}
}
} <span class="comment">// end match r</span>
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_cached_grouptoken</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="ident">grp_id</span>: <span class="kw-2">&amp;</span><span class="ident">Id</span>,
) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(<span class="ident">bool</span>, <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnixGroupToken</span><span class="op">&gt;</span>), ()<span class="op">&gt;</span> {
<span class="comment">// grp_id could be:</span>
<span class="comment">// * gidnumber</span>
<span class="comment">// * name</span>
<span class="comment">// * spn</span>
<span class="comment">// * uuid</span>
<span class="comment">// Attempt to search these in the db.</span>
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">r</span> <span class="op">=</span> <span class="ident">dbtxn</span>.<span class="ident">get_group</span>(<span class="kw-2">&amp;</span><span class="ident">grp_id</span>)<span class="question-mark">?</span>;
<span class="kw">match</span> <span class="ident">r</span> {
<span class="prelude-val">Some</span>((<span class="ident">ut</span>, <span class="ident">ex</span>)) =&gt; {
<span class="comment">// Are we expired?</span>
<span class="kw">let</span> <span class="ident">offset</span> <span class="op">=</span> <span class="ident">Duration::from_secs</span>(<span class="ident">ex</span>);
<span class="kw">let</span> <span class="ident">ex_time</span> <span class="op">=</span> <span class="ident">SystemTime::UNIX_EPOCH</span> <span class="op">+</span> <span class="ident">offset</span>;
<span class="kw">let</span> <span class="ident">now</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>();
<span class="kw">if</span> <span class="ident">now</span> <span class="op">&gt;</span><span class="op">=</span> <span class="ident">ex_time</span> {
<span class="prelude-val">Ok</span>((<span class="bool-val">true</span>, <span class="prelude-val">Some</span>(<span class="ident">ut</span>)))
} <span class="kw">else</span> {
<span class="prelude-val">Ok</span>((<span class="bool-val">false</span>, <span class="prelude-val">Some</span>(<span class="ident">ut</span>)))
}
}
<span class="prelude-val">None</span> =&gt; {
<span class="comment">// it wasn&#39;t in the DB - lets see if it&#39;s in the nxcache.</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">nxcache_txn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">nxcache</span>.<span class="ident">lock</span>().<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">nxcache_txn</span>.<span class="ident">get</span>(<span class="ident">grp_id</span>) {
<span class="prelude-val">Some</span>(<span class="ident">ex_time</span>) =&gt; {
<span class="kw">let</span> <span class="ident">now</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>();
<span class="kw">if</span> <span class="kw-2">&amp;</span><span class="ident">now</span> <span class="op">&gt;</span><span class="op">=</span> <span class="ident">ex_time</span> {
<span class="comment">// It&#39;s in the LRU, but we are past the expiry so</span>
<span class="comment">// lets attempt a refresh.</span>
<span class="prelude-val">Ok</span>((<span class="bool-val">true</span>, <span class="prelude-val">None</span>))
} <span class="kw">else</span> {
<span class="comment">// It&#39;s in the LRU and still valid, so return that</span>
<span class="comment">// no check is needed.</span>
<span class="prelude-val">Ok</span>((<span class="bool-val">false</span>, <span class="prelude-val">None</span>))
}
}
<span class="prelude-val">None</span> =&gt; {
<span class="comment">// Not in the LRU. Return that this IS expired</span>
<span class="comment">// and we have no data.</span>
<span class="prelude-val">Ok</span>((<span class="bool-val">true</span>, <span class="prelude-val">None</span>))
}
}
}
}
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">set_cache_usertoken</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">token</span>: <span class="kw-2">&amp;mut</span> <span class="ident">UnixUserToken</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), ()<span class="op">&gt;</span> {
<span class="comment">// Set an expiry</span>
<span class="kw">let</span> <span class="ident">ex_time</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>() <span class="op">+</span> <span class="ident">Duration::from_secs</span>(<span class="self">self</span>.<span class="ident">timeout_seconds</span>);
<span class="kw">let</span> <span class="ident">offset</span> <span class="op">=</span> <span class="ident">ex_time</span>
.<span class="ident">duration_since</span>(<span class="ident">SystemTime::UNIX_EPOCH</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;time conversion error - ex_time less than epoch? {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="comment">// WIP #392</span>
<span class="comment">// Check if requested `shell` exists on the system, else use `default_shell`</span>
<span class="kw">let</span> <span class="ident">requested_shell_exists</span>: <span class="ident">bool</span> <span class="op">=</span> <span class="ident">token</span>
.<span class="ident">shell</span>
.<span class="ident">as_ref</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">shell</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">exists</span> <span class="op">=</span> <span class="ident">Path::new</span>(<span class="ident">shell</span>).<span class="ident">exists</span>();
<span class="kw">if</span> <span class="op">!</span><span class="ident">exists</span> {
<span class="macro">info!</span>(
<span class="string">&quot;User requested shell is not present on this system - {}&quot;</span>,
<span class="ident">shell</span>
)
}
<span class="ident">exists</span>
})
.<span class="ident">unwrap_or_else</span>(<span class="op">|</span><span class="op">|</span> {
<span class="macro">info!</span>(<span class="string">&quot;User has not specified a shell, using default&quot;</span>);
<span class="bool-val">false</span>
});
<span class="kw">if</span> <span class="op">!</span><span class="ident">requested_shell_exists</span> {
<span class="ident">token</span>.<span class="ident">shell</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="self">self</span>.<span class="ident">default_shell</span>.<span class="ident">clone</span>())
}
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="comment">// We need to add the groups first</span>
<span class="ident">token</span>
.<span class="ident">groups</span>
.<span class="ident">iter</span>()
.<span class="ident">try_for_each</span>(<span class="op">|</span><span class="ident">g</span><span class="op">|</span> <span class="ident">dbtxn</span>.<span class="ident">update_group</span>(<span class="ident">g</span>, <span class="ident">offset</span>.<span class="ident">as_secs</span>()))
.<span class="ident">and_then</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span>
<span class="comment">// So that when we add the account it can make the relationships.</span>
<span class="ident">dbtxn</span>
.<span class="ident">update_account</span>(<span class="ident">token</span>, <span class="ident">offset</span>.<span class="ident">as_secs</span>()))
.<span class="ident">and_then</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="ident">dbtxn</span>.<span class="ident">commit</span>())
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">set_cache_grouptoken</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">token</span>: <span class="kw-2">&amp;</span><span class="ident">UnixGroupToken</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), ()<span class="op">&gt;</span> {
<span class="comment">// Set an expiry</span>
<span class="kw">let</span> <span class="ident">ex_time</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>() <span class="op">+</span> <span class="ident">Duration::from_secs</span>(<span class="self">self</span>.<span class="ident">timeout_seconds</span>);
<span class="kw">let</span> <span class="ident">offset</span> <span class="op">=</span> <span class="ident">ex_time</span>
.<span class="ident">duration_since</span>(<span class="ident">SystemTime::UNIX_EPOCH</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;time conversion error - ex_time less than epoch? {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>
.<span class="ident">update_group</span>(<span class="ident">token</span>, <span class="ident">offset</span>.<span class="ident">as_secs</span>())
.<span class="ident">and_then</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="ident">dbtxn</span>.<span class="ident">commit</span>())
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">delete_cache_usertoken</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">a_uuid</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="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>.<span class="ident">delete_account</span>(<span class="ident">a_uuid</span>).<span class="ident">and_then</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="ident">dbtxn</span>.<span class="ident">commit</span>())
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">delete_cache_grouptoken</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">g_uuid</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="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>.<span class="ident">delete_group</span>(<span class="ident">g_uuid</span>).<span class="ident">and_then</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="ident">dbtxn</span>.<span class="ident">commit</span>())
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">set_cache_userpassword</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">a_uuid</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="ident">cred</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="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>
.<span class="ident">update_account_password</span>(<span class="ident">a_uuid</span>, <span class="ident">cred</span>)
.<span class="ident">and_then</span>(<span class="op">|</span><span class="ident">x</span><span class="op">|</span> <span class="ident">dbtxn</span>.<span class="ident">commit</span>().<span class="ident">map</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="ident">x</span>))
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">check_cache_userpassword</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">a_uuid</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="ident">cred</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">bool</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>
.<span class="ident">check_account_password</span>(<span class="ident">a_uuid</span>, <span class="ident">cred</span>)
.<span class="ident">and_then</span>(<span class="op">|</span><span class="ident">x</span><span class="op">|</span> <span class="ident">dbtxn</span>.<span class="ident">commit</span>().<span class="ident">map</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="ident">x</span>))
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">refresh_usertoken</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="ident">account_id</span>: <span class="kw-2">&amp;</span><span class="ident">Id</span>,
<span class="ident">token</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnixUserToken</span><span class="op">&gt;</span>,
) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnixUserToken</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">match</span> <span class="self">self</span>
.<span class="ident">client</span>
.<span class="ident">read</span>()
.<span class="kw">await</span>
.<span class="ident">idm_account_unix_token_get</span>(<span class="ident">account_id</span>.<span class="ident">to_string</span>().<span class="ident">as_str</span>())
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="kw-2">mut</span> <span class="ident">n_tok</span>) =&gt; {
<span class="comment">// We have the token!</span>
<span class="self">self</span>.<span class="ident">set_cache_usertoken</span>(<span class="kw-2">&amp;mut</span> <span class="ident">n_tok</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">n_tok</span>))
}
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="kw">match</span> <span class="ident">e</span> {
<span class="ident">ClientError::Transport</span>(<span class="ident">er</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;transport error, moving to offline -&gt; {:?}&quot;</span>, <span class="ident">er</span>);
<span class="comment">// Something went wrong, mark offline.</span>
<span class="kw">let</span> <span class="ident">time</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>().<span class="ident">add</span>(<span class="ident">Duration::from_secs</span>(<span class="number">15</span>));
<span class="self">self</span>.<span class="ident">set_cachestate</span>(<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>))
.<span class="kw">await</span>;
<span class="prelude-val">Ok</span>(<span class="ident">token</span>)
}
<span class="ident">ClientError::Http</span>(<span class="ident">StatusCode::UNAUTHORIZED</span>, <span class="ident">reason</span>, <span class="ident">opid</span>) =&gt; {
<span class="kw">match</span> <span class="ident">reason</span> {
<span class="prelude-val">Some</span>(<span class="ident">OperationError::NotAuthenticated</span>) =&gt;
<span class="macro">warn!</span>(<span class="string">&quot;session not authenticated - attempting reauthentication - eventid {}&quot;</span>, <span class="ident">opid</span>),
<span class="prelude-val">Some</span>(<span class="ident">OperationError::SessionExpired</span>) =&gt;
<span class="macro">warn!</span>(<span class="string">&quot;session expired - attempting reauthentication - eventid {}&quot;</span>, <span class="ident">opid</span>),
<span class="ident">e</span> =&gt;
<span class="macro">error!</span>(
<span class="string">&quot;authentication error {:?}, moving to offline - eventid {}&quot;</span>, <span class="ident">e</span>, <span class="ident">opid</span>
),
};
<span class="comment">// Something went wrong, mark offline to force a re-auth ASAP.</span>
<span class="kw">let</span> <span class="ident">time</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>().<span class="ident">sub</span>(<span class="ident">Duration::from_secs</span>(<span class="number">1</span>));
<span class="self">self</span>.<span class="ident">set_cachestate</span>(<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>))
.<span class="kw">await</span>;
<span class="prelude-val">Ok</span>(<span class="ident">token</span>)
}
<span class="ident">ClientError::Http</span>(
<span class="ident">StatusCode::BAD_REQUEST</span>,
<span class="prelude-val">Some</span>(<span class="ident">OperationError::NoMatchingEntries</span>),
<span class="ident">opid</span>,
)
<span class="op">|</span> <span class="ident">ClientError::Http</span>(
<span class="ident">StatusCode::NOT_FOUND</span>,
<span class="prelude-val">Some</span>(<span class="ident">OperationError::NoMatchingEntries</span>),
<span class="ident">opid</span>,
)
<span class="op">|</span> <span class="ident">ClientError::Http</span>(
<span class="ident">StatusCode::BAD_REQUEST</span>,
<span class="prelude-val">Some</span>(<span class="ident">OperationError::InvalidAccountState</span>(<span class="kw">_</span>)),
<span class="ident">opid</span>,
) =&gt; {
<span class="comment">// We wele able to contact the server but the entry has been removed, or</span>
<span class="comment">// is not longer a valid posix account.</span>
<span class="macro">debug!</span>(<span class="string">&quot;entry has been removed or is no longer a valid posix account, clearing from cache ... - eventid {}&quot;</span>, <span class="ident">opid</span>);
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">tok</span>) <span class="op">=</span> <span class="ident">token</span> {
<span class="self">self</span>.<span class="ident">delete_cache_usertoken</span>(<span class="kw-2">&amp;</span><span class="ident">tok</span>.<span class="ident">uuid</span>).<span class="kw">await</span><span class="question-mark">?</span>;
};
<span class="comment">// Cache the NX here.</span>
<span class="self">self</span>.<span class="ident">set_nxcache</span>(<span class="ident">account_id</span>).<span class="kw">await</span>;
<span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>)
}
<span class="ident">er</span> =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;client error -&gt; {:?}&quot;</span>, <span class="ident">er</span>);
<span class="comment">// Some other transient error, continue with the token.</span>
<span class="prelude-val">Ok</span>(<span class="ident">token</span>)
}
}
}
}
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">refresh_grouptoken</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="ident">grp_id</span>: <span class="kw-2">&amp;</span><span class="ident">Id</span>,
<span class="ident">token</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnixGroupToken</span><span class="op">&gt;</span>,
) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnixGroupToken</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">match</span> <span class="self">self</span>
.<span class="ident">client</span>
.<span class="ident">read</span>()
.<span class="kw">await</span>
.<span class="ident">idm_group_unix_token_get</span>(<span class="ident">grp_id</span>.<span class="ident">to_string</span>().<span class="ident">as_str</span>())
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">n_tok</span>) =&gt; {
<span class="comment">// We have the token!</span>
<span class="self">self</span>.<span class="ident">set_cache_grouptoken</span>(<span class="kw-2">&amp;</span><span class="ident">n_tok</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">n_tok</span>))
}
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="kw">match</span> <span class="ident">e</span> {
<span class="ident">ClientError::Transport</span>(<span class="ident">er</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;transport error, moving to offline -&gt; {:?}&quot;</span>, <span class="ident">er</span>);
<span class="comment">// Something went wrong, mark offline.</span>
<span class="kw">let</span> <span class="ident">time</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>().<span class="ident">add</span>(<span class="ident">Duration::from_secs</span>(<span class="number">15</span>));
<span class="self">self</span>.<span class="ident">set_cachestate</span>(<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>))
.<span class="kw">await</span>;
<span class="prelude-val">Ok</span>(<span class="ident">token</span>)
}
<span class="ident">ClientError::Http</span>(
<span class="ident">StatusCode::UNAUTHORIZED</span>,
<span class="prelude-val">Some</span>(<span class="ident">OperationError::NotAuthenticated</span>),
<span class="ident">opid</span>,
) =&gt; {
<span class="macro">error!</span>(
<span class="string">&quot;transport unauthenticated, moving to offline - eventid {}&quot;</span>,
<span class="ident">opid</span>
);
<span class="comment">// Something went wrong, mark offline.</span>
<span class="kw">let</span> <span class="ident">time</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>().<span class="ident">add</span>(<span class="ident">Duration::from_secs</span>(<span class="number">15</span>));
<span class="self">self</span>.<span class="ident">set_cachestate</span>(<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>))
.<span class="kw">await</span>;
<span class="prelude-val">Ok</span>(<span class="ident">token</span>)
}
<span class="ident">ClientError::Http</span>(
<span class="ident">StatusCode::BAD_REQUEST</span>,
<span class="prelude-val">Some</span>(<span class="ident">OperationError::NoMatchingEntries</span>),
<span class="ident">opid</span>,
)
<span class="op">|</span> <span class="ident">ClientError::Http</span>(
<span class="ident">StatusCode::NOT_FOUND</span>,
<span class="prelude-val">Some</span>(<span class="ident">OperationError::NoMatchingEntries</span>),
<span class="ident">opid</span>,
)
<span class="op">|</span> <span class="ident">ClientError::Http</span>(
<span class="ident">StatusCode::BAD_REQUEST</span>,
<span class="prelude-val">Some</span>(<span class="ident">OperationError::InvalidAccountState</span>(<span class="kw">_</span>)),
<span class="ident">opid</span>,
) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;entry has been removed or is no longer a valid posix group, clearing from cache ... - eventid {}&quot;</span>, <span class="ident">opid</span>);
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">tok</span>) <span class="op">=</span> <span class="ident">token</span> {
<span class="self">self</span>.<span class="ident">delete_cache_grouptoken</span>(<span class="kw-2">&amp;</span><span class="ident">tok</span>.<span class="ident">uuid</span>).<span class="kw">await</span><span class="question-mark">?</span>;
};
<span class="comment">// Cache the NX here.</span>
<span class="self">self</span>.<span class="ident">set_nxcache</span>(<span class="ident">grp_id</span>).<span class="kw">await</span>;
<span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>)
}
<span class="ident">er</span> =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;client error -&gt; {:?}&quot;</span>, <span class="ident">er</span>);
<span class="comment">// Some other transient error, continue with the token.</span>
<span class="prelude-val">Ok</span>(<span class="ident">token</span>)
}
}
}
}
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_usertoken</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">account_id</span>: <span class="ident">Id</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnixUserToken</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="macro">debug!</span>(<span class="string">&quot;get_usertoken&quot;</span>);
<span class="comment">// get the item from the cache</span>
<span class="kw">let</span> (<span class="ident">expired</span>, <span class="ident">item</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_cached_usertoken</span>(<span class="kw-2">&amp;</span><span class="ident">account_id</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">debug!</span>(<span class="string">&quot;get_usertoken error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_cachestate</span>().<span class="kw">await</span>;
<span class="kw">match</span> (<span class="ident">expired</span>, <span class="ident">state</span>) {
(<span class="kw">_</span>, <span class="ident">CacheState::Offline</span>) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;offline, returning cached item&quot;</span>);
<span class="prelude-val">Ok</span>(<span class="ident">item</span>)
}
(<span class="bool-val">false</span>, <span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>)) =&gt; {
<span class="macro">debug!</span>(
<span class="string">&quot;offline valid, next check {:?}, returning cached item&quot;</span>,
<span class="ident">time</span>
);
<span class="comment">// Still valid within lifetime, return.</span>
<span class="prelude-val">Ok</span>(<span class="ident">item</span>)
}
(<span class="bool-val">false</span>, <span class="ident">CacheState::Online</span>) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;online valid, returning cached item&quot;</span>);
<span class="comment">// Still valid within lifetime, return.</span>
<span class="prelude-val">Ok</span>(<span class="ident">item</span>)
}
(<span class="bool-val">true</span>, <span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>)) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;offline expired, next check {:?}, refresh cache&quot;</span>, <span class="ident">time</span>);
<span class="comment">// Attempt to refresh the item</span>
<span class="comment">// Return it.</span>
<span class="kw">if</span> <span class="ident">SystemTime::now</span>() <span class="op">&gt;</span><span class="op">=</span> <span class="ident">time</span> <span class="op">&amp;&amp;</span> <span class="self">self</span>.<span class="ident">test_connection</span>().<span class="kw">await</span> {
<span class="comment">// We brought ourselves online, lets go</span>
<span class="self">self</span>.<span class="ident">refresh_usertoken</span>(<span class="kw-2">&amp;</span><span class="ident">account_id</span>, <span class="ident">item</span>).<span class="kw">await</span>
} <span class="kw">else</span> {
<span class="comment">// Unable to bring up connection, return cache.</span>
<span class="prelude-val">Ok</span>(<span class="ident">item</span>)
}
}
(<span class="bool-val">true</span>, <span class="ident">CacheState::Online</span>) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;online expired, refresh cache&quot;</span>);
<span class="comment">// Attempt to refresh the item</span>
<span class="comment">// Return it.</span>
<span class="self">self</span>.<span class="ident">refresh_usertoken</span>(<span class="kw-2">&amp;</span><span class="ident">account_id</span>, <span class="ident">item</span>).<span class="kw">await</span>
}
}
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">t</span><span class="op">|</span> {
<span class="macro">debug!</span>(<span class="string">&quot;token -&gt; {:?}&quot;</span>, <span class="ident">t</span>);
<span class="ident">t</span>
})
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_grouptoken</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">grp_id</span>: <span class="ident">Id</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnixGroupToken</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="macro">debug!</span>(<span class="string">&quot;get_grouptoken&quot;</span>);
<span class="kw">let</span> (<span class="ident">expired</span>, <span class="ident">item</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_cached_grouptoken</span>(<span class="kw-2">&amp;</span><span class="ident">grp_id</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">debug!</span>(<span class="string">&quot;get_grouptoken error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
})<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_cachestate</span>().<span class="kw">await</span>;
<span class="kw">match</span> (<span class="ident">expired</span>, <span class="ident">state</span>) {
(<span class="kw">_</span>, <span class="ident">CacheState::Offline</span>) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;offline, returning cached item&quot;</span>);
<span class="prelude-val">Ok</span>(<span class="ident">item</span>)
}
(<span class="bool-val">false</span>, <span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>)) =&gt; {
<span class="macro">debug!</span>(
<span class="string">&quot;offline valid, next check {:?}, returning cached item&quot;</span>,
<span class="ident">time</span>
);
<span class="comment">// Still valid within lifetime, return.</span>
<span class="prelude-val">Ok</span>(<span class="ident">item</span>)
}
(<span class="bool-val">false</span>, <span class="ident">CacheState::Online</span>) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;online valid, returning cached item&quot;</span>);
<span class="comment">// Still valid within lifetime, return.</span>
<span class="prelude-val">Ok</span>(<span class="ident">item</span>)
}
(<span class="bool-val">true</span>, <span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>)) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;offline expired, next check {:?}, refresh cache&quot;</span>, <span class="ident">time</span>);
<span class="comment">// Attempt to refresh the item</span>
<span class="comment">// Return it.</span>
<span class="kw">if</span> <span class="ident">SystemTime::now</span>() <span class="op">&gt;</span><span class="op">=</span> <span class="ident">time</span> <span class="op">&amp;&amp;</span> <span class="self">self</span>.<span class="ident">test_connection</span>().<span class="kw">await</span> {
<span class="comment">// We brought ourselves online, lets go</span>
<span class="self">self</span>.<span class="ident">refresh_grouptoken</span>(<span class="kw-2">&amp;</span><span class="ident">grp_id</span>, <span class="ident">item</span>).<span class="kw">await</span>
} <span class="kw">else</span> {
<span class="comment">// Unable to bring up connection, return cache.</span>
<span class="prelude-val">Ok</span>(<span class="ident">item</span>)
}
}
(<span class="bool-val">true</span>, <span class="ident">CacheState::Online</span>) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;online expired, refresh cache&quot;</span>);
<span class="comment">// Attempt to refresh the item</span>
<span class="comment">// Return it.</span>
<span class="self">self</span>.<span class="ident">refresh_grouptoken</span>(<span class="kw-2">&amp;</span><span class="ident">grp_id</span>, <span class="ident">item</span>).<span class="kw">await</span>
}
}
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_groupmembers</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">uuid</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>) -&gt; <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">dbtxn</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">db</span>.<span class="ident">write</span>().<span class="kw">await</span>;
<span class="ident">dbtxn</span>
.<span class="ident">get_group_members</span>(<span class="ident">uuid</span>)
.<span class="ident">unwrap_or_else</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="ident">Vec::new</span>())
.<span class="ident">into_iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">ut</span><span class="op">|</span> <span class="self">self</span>.<span class="ident">token_uidattr</span>(<span class="kw-2">&amp;</span><span class="ident">ut</span>))
.<span class="ident">collect</span>()
}
<span class="comment">// Get ssh keys for an account id</span>
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_sshkeys</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">account_id</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">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">token</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_usertoken</span>(<span class="ident">Id::Name</span>(<span class="ident">account_id</span>.<span class="ident">to_string</span>())).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="ident">token</span>
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">t</span><span class="op">|</span> {
<span class="comment">// Only return keys if the account is valid</span>
<span class="kw">if</span> <span class="ident">t</span>.<span class="ident">valid</span> {
<span class="ident">t</span>.<span class="ident">sshkeys</span>
} <span class="kw">else</span> {
<span class="ident">Vec::with_capacity</span>(<span class="number">0</span>)
}
})
.<span class="ident">unwrap_or_else</span>(<span class="op">|</span><span class="op">|</span> <span class="ident">Vec::with_capacity</span>(<span class="number">0</span>)))
}
<span class="attribute">#[<span class="ident">inline</span>(<span class="ident">always</span>)]</span>
<span class="kw">fn</span> <span class="ident">token_homedirectory_alias</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">token</span>: <span class="kw-2">&amp;</span><span class="ident">UnixUserToken</span>) -&gt; <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">home_alias</span>.<span class="ident">map</span>(<span class="op">|</span><span class="ident">t</span><span class="op">|</span> <span class="kw">match</span> <span class="ident">t</span> {
<span class="comment">// If we have an alias. use it.</span>
<span class="ident">HomeAttr::Uuid</span> =&gt; <span class="ident">token</span>.<span class="ident">uuid</span>.<span class="ident">as_str</span>().<span class="ident">to_string</span>(),
<span class="ident">HomeAttr::Spn</span> =&gt; <span class="ident">token</span>.<span class="ident">spn</span>.<span class="ident">as_str</span>().<span class="ident">to_string</span>(),
<span class="ident">HomeAttr::Name</span> =&gt; <span class="ident">token</span>.<span class="ident">name</span>.<span class="ident">as_str</span>().<span class="ident">to_string</span>(),
})
}
<span class="attribute">#[<span class="ident">inline</span>(<span class="ident">always</span>)]</span>
<span class="kw">fn</span> <span class="ident">token_homedirectory_attr</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">token</span>: <span class="kw-2">&amp;</span><span class="ident">UnixUserToken</span>) -&gt; <span class="ident">String</span> {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">home_attr</span> {
<span class="ident">HomeAttr::Uuid</span> =&gt; <span class="ident">token</span>.<span class="ident">uuid</span>.<span class="ident">as_str</span>().<span class="ident">to_string</span>(),
<span class="ident">HomeAttr::Spn</span> =&gt; <span class="ident">token</span>.<span class="ident">spn</span>.<span class="ident">as_str</span>().<span class="ident">to_string</span>(),
<span class="ident">HomeAttr::Name</span> =&gt; <span class="ident">token</span>.<span class="ident">name</span>.<span class="ident">as_str</span>().<span class="ident">to_string</span>(),
}
}
<span class="attribute">#[<span class="ident">inline</span>(<span class="ident">always</span>)]</span>
<span class="kw">fn</span> <span class="ident">token_homedirectory</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">token</span>: <span class="kw-2">&amp;</span><span class="ident">UnixUserToken</span>) -&gt; <span class="ident">String</span> {
<span class="self">self</span>.<span class="ident">token_homedirectory_alias</span>(<span class="ident">token</span>)
.<span class="ident">unwrap_or_else</span>(<span class="op">|</span><span class="op">|</span> <span class="self">self</span>.<span class="ident">token_homedirectory_attr</span>(<span class="ident">token</span>))
}
<span class="attribute">#[<span class="ident">inline</span>(<span class="ident">always</span>)]</span>
<span class="kw">fn</span> <span class="ident">token_abs_homedirectory</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">token</span>: <span class="kw-2">&amp;</span><span class="ident">UnixUserToken</span>) -&gt; <span class="ident">String</span> {
<span class="macro">format!</span>(<span class="string">&quot;{}{}&quot;</span>, <span class="self">self</span>.<span class="ident">home_prefix</span>, <span class="self">self</span>.<span class="ident">token_homedirectory</span>(<span class="ident">token</span>))
}
<span class="attribute">#[<span class="ident">inline</span>(<span class="ident">always</span>)]</span>
<span class="kw">fn</span> <span class="ident">token_uidattr</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">token</span>: <span class="kw-2">&amp;</span><span class="ident">UnixUserToken</span>) -&gt; <span class="ident">String</span> {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">uid_attr_map</span> {
<span class="ident">UidAttr::Spn</span> =&gt; <span class="ident">token</span>.<span class="ident">spn</span>.<span class="ident">as_str</span>(),
<span class="ident">UidAttr::Name</span> =&gt; <span class="ident">token</span>.<span class="ident">name</span>.<span class="ident">as_str</span>(),
}
.<span class="ident">to_string</span>()
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_nssaccounts</span>(<span class="kw-2">&amp;</span><span class="self">self</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">NssUser</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">get_cached_usertokens</span>().<span class="kw">await</span>.<span class="ident">map</span>(<span class="op">|</span><span class="ident">l</span><span class="op">|</span> {
<span class="ident">l</span>.<span class="ident">into_iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">tok</span><span class="op">|</span> <span class="ident">NssUser</span> {
<span class="ident">homedir</span>: <span class="self">self</span>.<span class="ident">token_abs_homedirectory</span>(<span class="kw-2">&amp;</span><span class="ident">tok</span>),
<span class="ident">name</span>: <span class="self">self</span>.<span class="ident">token_uidattr</span>(<span class="kw-2">&amp;</span><span class="ident">tok</span>),
<span class="ident">gid</span>: <span class="ident">tok</span>.<span class="ident">gidnumber</span>,
<span class="ident">gecos</span>: <span class="ident">tok</span>.<span class="ident">displayname</span>,
<span class="ident">shell</span>: <span class="ident">tok</span>.<span class="ident">shell</span>.<span class="ident">unwrap_or_else</span>(<span class="op">|</span><span class="op">|</span> <span class="self">self</span>.<span class="ident">default_shell</span>.<span class="ident">clone</span>()),
})
.<span class="ident">collect</span>()
})
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_nssaccount</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">account_id</span>: <span class="ident">Id</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">NssUser</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">token</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_usertoken</span>(<span class="ident">account_id</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="ident">token</span>.<span class="ident">map</span>(<span class="op">|</span><span class="ident">tok</span><span class="op">|</span> <span class="ident">NssUser</span> {
<span class="ident">homedir</span>: <span class="self">self</span>.<span class="ident">token_abs_homedirectory</span>(<span class="kw-2">&amp;</span><span class="ident">tok</span>),
<span class="ident">name</span>: <span class="self">self</span>.<span class="ident">token_uidattr</span>(<span class="kw-2">&amp;</span><span class="ident">tok</span>),
<span class="ident">gid</span>: <span class="ident">tok</span>.<span class="ident">gidnumber</span>,
<span class="ident">gecos</span>: <span class="ident">tok</span>.<span class="ident">displayname</span>,
<span class="ident">shell</span>: <span class="ident">tok</span>.<span class="ident">shell</span>.<span class="ident">unwrap_or_else</span>(<span class="op">|</span><span class="op">|</span> <span class="self">self</span>.<span class="ident">default_shell</span>.<span class="ident">clone</span>()),
}))
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_nssaccount_name</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">account_id</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="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">NssUser</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">get_nssaccount</span>(<span class="ident">Id::Name</span>(<span class="ident">account_id</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">get_nssaccount_gid</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">gid</span>: <span class="ident">u32</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">NssUser</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">get_nssaccount</span>(<span class="ident">Id::Gid</span>(<span class="ident">gid</span>)).<span class="kw">await</span>
}
<span class="attribute">#[<span class="ident">inline</span>(<span class="ident">always</span>)]</span>
<span class="kw">fn</span> <span class="ident">token_gidattr</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">token</span>: <span class="kw-2">&amp;</span><span class="ident">UnixGroupToken</span>) -&gt; <span class="ident">String</span> {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">gid_attr_map</span> {
<span class="ident">UidAttr::Spn</span> =&gt; <span class="ident">token</span>.<span class="ident">spn</span>.<span class="ident">as_str</span>(),
<span class="ident">UidAttr::Name</span> =&gt; <span class="ident">token</span>.<span class="ident">name</span>.<span class="ident">as_str</span>(),
}
.<span class="ident">to_string</span>()
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_nssgroups</span>(<span class="kw-2">&amp;</span><span class="self">self</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">NssGroup</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">l</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_cached_grouptokens</span>().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">r</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">l</span>.<span class="ident">len</span>());
<span class="kw">for</span> <span class="ident">tok</span> <span class="kw">in</span> <span class="ident">l</span>.<span class="ident">into_iter</span>() {
<span class="kw">let</span> <span class="ident">members</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_groupmembers</span>(<span class="kw-2">&amp;</span><span class="ident">tok</span>.<span class="ident">uuid</span>).<span class="kw">await</span>;
<span class="ident">r</span>.<span class="ident">push</span>(<span class="ident">NssGroup</span> {
<span class="ident">name</span>: <span class="self">self</span>.<span class="ident">token_gidattr</span>(<span class="kw-2">&amp;</span><span class="ident">tok</span>),
<span class="ident">gid</span>: <span class="ident">tok</span>.<span class="ident">gidnumber</span>,
<span class="ident">members</span>,
})
}
<span class="prelude-val">Ok</span>(<span class="ident">r</span>)
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_nssgroup</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">grp_id</span>: <span class="ident">Id</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">NssGroup</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">token</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_grouptoken</span>(<span class="ident">grp_id</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="comment">// Get members set.</span>
<span class="kw">match</span> <span class="ident">token</span> {
<span class="prelude-val">Some</span>(<span class="ident">tok</span>) =&gt; {
<span class="kw">let</span> <span class="ident">members</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_groupmembers</span>(<span class="kw-2">&amp;</span><span class="ident">tok</span>.<span class="ident">uuid</span>).<span class="kw">await</span>;
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">NssGroup</span> {
<span class="ident">name</span>: <span class="self">self</span>.<span class="ident">token_gidattr</span>(<span class="kw-2">&amp;</span><span class="ident">tok</span>),
<span class="ident">gid</span>: <span class="ident">tok</span>.<span class="ident">gidnumber</span>,
<span class="ident">members</span>,
}))
}
<span class="prelude-val">None</span> =&gt; <span class="prelude-val">Ok</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">get_nssgroup_name</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">grp_id</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="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">NssGroup</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">get_nssgroup</span>(<span class="ident">Id::Name</span>(<span class="ident">grp_id</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">get_nssgroup_gid</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">gid</span>: <span class="ident">u32</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">NssGroup</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">get_nssgroup</span>(<span class="ident">Id::Gid</span>(<span class="ident">gid</span>)).<span class="kw">await</span>
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">online_account_authenticate</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="ident">token</span>: <span class="kw-2">&amp;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnixUserToken</span><span class="op">&gt;</span>,
<span class="ident">account_id</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>,
<span class="ident">cred</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="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">bool</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="macro">debug!</span>(<span class="string">&quot;Attempt online password check&quot;</span>);
<span class="comment">// We are online, attempt the pw to the server.</span>
<span class="kw">match</span> <span class="self">self</span>
.<span class="ident">client</span>
.<span class="ident">read</span>()
.<span class="kw">await</span>
.<span class="ident">idm_account_unix_cred_verify</span>(<span class="ident">account_id</span>, <span class="ident">cred</span>)
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="kw-2">mut</span> <span class="ident">n_tok</span>)) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;online password check success.&quot;</span>);
<span class="self">self</span>.<span class="ident">set_cache_usertoken</span>(<span class="kw-2">&amp;mut</span> <span class="ident">n_tok</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="self">self</span>.<span class="ident">set_cache_userpassword</span>(<span class="kw-2">&amp;</span><span class="ident">n_tok</span>.<span class="ident">uuid</span>, <span class="ident">cred</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
}
<span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;incorrect password&quot;</span>);
<span class="comment">// PW failed the check.</span>
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="bool-val">false</span>))
}
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="kw">match</span> <span class="ident">e</span> {
<span class="ident">ClientError::Transport</span>(<span class="ident">er</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;transport error, moving to offline -&gt; {:?}&quot;</span>, <span class="ident">er</span>);
<span class="comment">// Something went wrong, mark offline.</span>
<span class="kw">let</span> <span class="ident">time</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>().<span class="ident">add</span>(<span class="ident">Duration::from_secs</span>(<span class="number">15</span>));
<span class="self">self</span>.<span class="ident">set_cachestate</span>(<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>))
.<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">token</span>.<span class="ident">as_ref</span>() {
<span class="prelude-val">Some</span>(<span class="ident">t</span>) =&gt; <span class="self">self</span>.<span class="ident">check_cache_userpassword</span>(<span class="kw-2">&amp;</span><span class="ident">t</span>.<span class="ident">uuid</span>, <span class="ident">cred</span>).<span class="kw">await</span>.<span class="ident">map</span>(<span class="prelude-val">Some</span>),
<span class="prelude-val">None</span> =&gt; <span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>),
}
}
<span class="ident">ClientError::Http</span>(<span class="ident">StatusCode::UNAUTHORIZED</span>, <span class="ident">reason</span>, <span class="ident">opid</span>) =&gt; {
<span class="kw">match</span> <span class="ident">reason</span> {
<span class="prelude-val">Some</span>(<span class="ident">OperationError::NotAuthenticated</span>) =&gt;
<span class="macro">warn!</span>(<span class="string">&quot;session not authenticated - attempting reauthentication - eventid {}&quot;</span>, <span class="ident">opid</span>),
<span class="prelude-val">Some</span>(<span class="ident">OperationError::SessionExpired</span>) =&gt;
<span class="macro">warn!</span>(<span class="string">&quot;session expired - attempting reauthentication - eventid {}&quot;</span>, <span class="ident">opid</span>),
<span class="ident">e</span> =&gt;
<span class="macro">error!</span>(
<span class="string">&quot;authentication error {:?}, moving to offline - eventid {}&quot;</span>, <span class="ident">e</span>, <span class="ident">opid</span>
),
};
<span class="comment">// Something went wrong, mark offline to force a re-auth ASAP.</span>
<span class="kw">let</span> <span class="ident">time</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>().<span class="ident">sub</span>(<span class="ident">Duration::from_secs</span>(<span class="number">1</span>));
<span class="self">self</span>.<span class="ident">set_cachestate</span>(<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>))
.<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">token</span>.<span class="ident">as_ref</span>() {
<span class="prelude-val">Some</span>(<span class="ident">t</span>) =&gt; <span class="self">self</span>.<span class="ident">check_cache_userpassword</span>(<span class="kw-2">&amp;</span><span class="ident">t</span>.<span class="ident">uuid</span>, <span class="ident">cred</span>).<span class="kw">await</span>.<span class="ident">map</span>(<span class="prelude-val">Some</span>),
<span class="prelude-val">None</span> =&gt; <span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>),
}
}
<span class="ident">ClientError::Http</span>(
<span class="ident">StatusCode::BAD_REQUEST</span>,
<span class="prelude-val">Some</span>(<span class="ident">OperationError::NoMatchingEntries</span>),
<span class="ident">opid</span>,
)
<span class="op">|</span> <span class="ident">ClientError::Http</span>(
<span class="ident">StatusCode::NOT_FOUND</span>,
<span class="prelude-val">Some</span>(<span class="ident">OperationError::NoMatchingEntries</span>),
<span class="ident">opid</span>,
)
<span class="op">|</span> <span class="ident">ClientError::Http</span>(
<span class="ident">StatusCode::BAD_REQUEST</span>,
<span class="prelude-val">Some</span>(<span class="ident">OperationError::InvalidAccountState</span>(<span class="kw">_</span>)),
<span class="ident">opid</span>,
) =&gt; {
<span class="macro">error!</span>(
<span class="string">&quot;unknown account or is not a valid posix account - eventid {}&quot;</span>,
<span class="ident">opid</span>
);
<span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>)
}
<span class="ident">er</span> =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;client error -&gt; {:?}&quot;</span>, <span class="ident">er</span>);
<span class="comment">// Some other unknown processing error?</span>
<span class="prelude-val">Err</span>(())
}
}
}
}
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">offline_account_authenticate</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="ident">token</span>: <span class="kw-2">&amp;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnixUserToken</span><span class="op">&gt;</span>,
<span class="ident">cred</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="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">bool</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="macro">debug!</span>(<span class="string">&quot;Attempt offline password check&quot;</span>);
<span class="kw">match</span> <span class="ident">token</span>.<span class="ident">as_ref</span>() {
<span class="prelude-val">Some</span>(<span class="ident">t</span>) =&gt; {
<span class="kw">if</span> <span class="ident">t</span>.<span class="ident">valid</span> {
<span class="self">self</span>.<span class="ident">check_cache_userpassword</span>(<span class="kw-2">&amp;</span><span class="ident">t</span>.<span class="ident">uuid</span>, <span class="ident">cred</span>).<span class="kw">await</span>.<span class="ident">map</span>(<span class="prelude-val">Some</span>)
} <span class="kw">else</span> {
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="bool-val">false</span>))
}
}
<span class="prelude-val">None</span> =&gt; <span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>),
}
<span class="comment">/*
token
.as_ref()
.map(async |t| self.check_cache_userpassword(&amp;t.uuid, cred).await)
.transpose()
*/</span>
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">pam_account_allowed</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">account_id</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="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">bool</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">token</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_usertoken</span>(<span class="ident">Id::Name</span>(<span class="ident">account_id</span>.<span class="ident">to_string</span>())).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">pam_allow_groups</span>.<span class="ident">len</span>() <span class="op">==</span> <span class="number">0</span> {
<span class="comment">// can&#39;t allow anything if the group list is zero...</span>
<span class="macro">eprintln!</span>(<span class="string">&quot;Cannot authenticate users, no allowed groups in configuration!&quot;</span>);
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="bool-val">false</span>))
} <span class="kw">else</span> {
<span class="prelude-val">Ok</span>(<span class="ident">token</span>.<span class="ident">map</span>(<span class="op">|</span><span class="ident">tok</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">user_set</span>: <span class="ident">BTreeSet</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">tok</span>
.<span class="ident">groups</span>
.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">g</span><span class="op">|</span> <span class="macro">vec!</span>[<span class="ident">g</span>.<span class="ident">name</span>.<span class="ident">clone</span>(), <span class="ident">g</span>.<span class="ident">spn</span>.<span class="ident">clone</span>(), <span class="ident">g</span>.<span class="ident">uuid</span>.<span class="ident">clone</span>()])
.<span class="ident">flatten</span>()
.<span class="ident">collect</span>();
<span class="macro">debug!</span>(
<span class="string">&quot;Checking if user is in allowed groups ({:?}) -&gt; {:?}&quot;</span>,
<span class="self">self</span>.<span class="ident">pam_allow_groups</span>, <span class="ident">user_set</span>,
);
<span class="kw">let</span> <span class="ident">intersection_count</span> <span class="op">=</span> <span class="ident">user_set</span>.<span class="ident">intersection</span>(<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">pam_allow_groups</span>).<span class="ident">count</span>();
<span class="macro">debug!</span>(<span class="string">&quot;Number of intersecting groups: {}&quot;</span>, <span class="ident">intersection_count</span>);
<span class="macro">debug!</span>(<span class="string">&quot;User has valid token: {}&quot;</span>, <span class="ident">tok</span>.<span class="ident">valid</span>);
<span class="ident">intersection_count</span> <span class="op">&gt;</span> <span class="number">0</span> <span class="op">&amp;&amp;</span> <span class="ident">tok</span>.<span class="ident">valid</span>
}))
}
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">pam_account_authenticate</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="ident">account_id</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>,
<span class="ident">cred</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="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">bool</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_cachestate</span>().<span class="kw">await</span>;
<span class="kw">let</span> (<span class="ident">_expired</span>, <span class="ident">token</span>) <span class="op">=</span> <span class="self">self</span>
.<span class="ident">get_cached_usertoken</span>(<span class="kw-2">&amp;</span><span class="ident">Id::Name</span>(<span class="ident">account_id</span>.<span class="ident">to_string</span>()))
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">match</span> <span class="ident">state</span> {
<span class="ident">CacheState::Online</span> =&gt; {
<span class="self">self</span>.<span class="ident">online_account_authenticate</span>(<span class="kw-2">&amp;</span><span class="ident">token</span>, <span class="ident">account_id</span>, <span class="ident">cred</span>)
.<span class="kw">await</span>
}
<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">_time</span>) =&gt; {
<span class="comment">// Always attempt to go online to attempt the authentication.</span>
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">test_connection</span>().<span class="kw">await</span> {
<span class="comment">// Brought ourselves online, lets check.</span>
<span class="self">self</span>.<span class="ident">online_account_authenticate</span>(<span class="kw-2">&amp;</span><span class="ident">token</span>, <span class="ident">account_id</span>, <span class="ident">cred</span>)
.<span class="kw">await</span>
} <span class="kw">else</span> {
<span class="comment">// We are offline, check from the cache if possible.</span>
<span class="self">self</span>.<span class="ident">offline_account_authenticate</span>(<span class="kw-2">&amp;</span><span class="ident">token</span>, <span class="ident">cred</span>).<span class="kw">await</span>
}
}
<span class="kw">_</span> =&gt; {
<span class="comment">// We are offline, check from the cache if possible.</span>
<span class="self">self</span>.<span class="ident">offline_account_authenticate</span>(<span class="kw-2">&amp;</span><span class="ident">token</span>, <span class="ident">cred</span>).<span class="kw">await</span>
}
}
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">pam_account_beginsession</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="ident">account_id</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="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">HomeDirectoryInfo</span><span class="op">&gt;</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">token</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_usertoken</span>(<span class="ident">Id::Name</span>(<span class="ident">account_id</span>.<span class="ident">to_string</span>())).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="ident">token</span>.<span class="ident">as_ref</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">tok</span><span class="op">|</span> <span class="ident">HomeDirectoryInfo</span> {
<span class="ident">gid</span>: <span class="ident">tok</span>.<span class="ident">gidnumber</span>,
<span class="ident">name</span>: <span class="self">self</span>.<span class="ident">token_homedirectory_attr</span>(<span class="ident">tok</span>),
<span class="ident">aliases</span>: <span class="self">self</span>
.<span class="ident">token_homedirectory_alias</span>(<span class="ident">tok</span>)
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="macro">vec!</span>[<span class="ident">s</span>])
.<span class="ident">unwrap_or_else</span>(<span class="ident">Vec::new</span>),
}))
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">test_connection</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="ident">bool</span> {
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_cachestate</span>().<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">state</span> {
<span class="ident">CacheState::Offline</span> =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;Offline -&gt; no change&quot;</span>);
<span class="bool-val">false</span>
}
<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">_time</span>) =&gt; {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">client</span>.<span class="ident">write</span>().<span class="kw">await</span>.<span class="ident">auth_anonymous</span>().<span class="kw">await</span> {
<span class="prelude-val">Ok</span>(<span class="ident">_uat</span>) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;OfflineNextCheck -&gt; authenticated&quot;</span>);
<span class="self">self</span>.<span class="ident">set_cachestate</span>(<span class="ident">CacheState::Online</span>).<span class="kw">await</span>;
<span class="bool-val">true</span>
}
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;OfflineNextCheck -&gt; disconnected, staying offline. {:?}&quot;</span>, <span class="ident">e</span>);
<span class="kw">let</span> <span class="ident">time</span> <span class="op">=</span> <span class="ident">SystemTime::now</span>().<span class="ident">add</span>(<span class="ident">Duration::from_secs</span>(<span class="number">15</span>));
<span class="self">self</span>.<span class="ident">set_cachestate</span>(<span class="ident">CacheState::OfflineNextCheck</span>(<span class="ident">time</span>))
.<span class="kw">await</span>;
<span class="bool-val">false</span>
}
}
}
<span class="ident">CacheState::Online</span> =&gt; {
<span class="macro">debug!</span>(<span class="string">&quot;Online, no change&quot;</span>);
<span class="bool-val">true</span>
}
}
}
}
</code></pre></div>
</section><section id="search" class="content hidden"></section></div></main><div id="rustdoc-vars" data-root-path="../../" data-current-crate="kanidm_unix_common" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.61.0 (fe5b13d68 2022-05-18)" ></div>
</body></html>