diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/go.mod b/go.mod index b056619..2367ecd 100644 --- a/go.mod +++ b/go.mod @@ -1,23 +1,29 @@ module github.com/Macmod/godap/v2 -go 1.21.4 +go 1.24.0 + +toolchain go1.24.4 require ( - github.com/gdamore/tcell/v2 v2.7.1 - github.com/go-asn1-ber/asn1-ber v1.5.5 - github.com/go-ldap/ldap v0.0.0-20240314174501-83a306c8f13f - github.com/go-ldap/ldap/v3 v3.4.7-0.20240314174501-83a306c8f13f + github.com/gdamore/tcell/v2 v2.9.0 + github.com/go-asn1-ber/asn1-ber v1.5.7 + github.com/go-ldap/ldap/v3 v3.4.12 github.com/jcmturner/gokrb5/v8 v8.4.4 - github.com/rivo/tview v0.0.0-20240413115534-b0d41c484b95 - github.com/spf13/cobra v1.8.0 - golang.org/x/text v0.14.0 + github.com/rivo/tview v0.42.0 + github.com/spf13/cobra v1.10.1 + github.com/spf13/pflag v1.0.10 + golang.org/x/term v0.36.0 + golang.org/x/text v0.30.0 h12.io/socks v1.0.3 + software.sslmate.com/src/go-pkcs12 v0.6.0 ) require ( github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect - github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect - github.com/gdamore/encoding v1.0.0 // indirect + github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e // indirect + github.com/clipperhouse/stringish v0.1.1 // indirect + github.com/clipperhouse/uax29/v2 v2.3.0 // indirect + github.com/gdamore/encoding v1.0.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -26,15 +32,12 @@ require ( github.com/jcmturner/gofork v1.7.6 // indirect github.com/jcmturner/goidentity/v6 v6.0.1 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/lucasb-eyer/go-colorful v1.3.0 // indirect + github.com/mattn/go-runewidth v0.0.19 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - software.sslmate.com/src/go-pkcs12 v0.5.0 // indirect + golang.org/x/crypto v0.43.0 // indirect + golang.org/x/net v0.46.0 // indirect + golang.org/x/sys v0.37.0 // indirect ) replace github.com/jcmturner/gokrb5/v8 => github.com/Macmod/gokrb5/v8 v8.4.5-0.20240428143821-ea9a660f0f44 diff --git a/go.sum b/go.sum index f234b54..cc7d309 100644 --- a/go.sum +++ b/go.sum @@ -4,22 +4,24 @@ github.com/Macmod/gokrb5/v8 v8.4.5-0.20240428143821-ea9a660f0f44 h1:+FClzEKhnNbI github.com/Macmod/gokrb5/v8 v8.4.5-0.20240428143821-ea9a660f0f44/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= github.com/Macmod/ldap/v3 v3.0.0-20240415020653-119bc6d73ac6 h1:HRMFt8yuQvKKuCUx4ImdjmowHMxmJwCiffyEqxB1Qx8= github.com/Macmod/ldap/v3 v3.0.0-20240415020653-119bc6d73ac6/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk= -github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= -github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= +github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= -github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= -github.com/gdamore/tcell/v2 v2.7.1 h1:TiCcmpWHiAU7F0rA2I3S2Y4mmLmO9KHxJ7E1QhYzQbc= -github.com/gdamore/tcell/v2 v2.7.1/go.mod h1:dSXtXTSK0VsW1biw65DZLZ2NKr7j0qP/0J7ONmsraWg= -github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= +github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= +github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo= +github.com/gdamore/tcell/v2 v2.9.0 h1:N6t+eqK7/xwtRPwxzs1PXeRWnm0H9l02CrgJ7DLn1ys= +github.com/gdamore/tcell/v2 v2.9.0/go.mod h1:8/ZoqM9rxzYphT9tH/9LnunhV9oPBqwS8WHGYm5nrmo= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-ldap/ldap v0.0.0-20240314174501-83a306c8f13f h1:Ut2osoWP+r8CybEuU7xg7AxOYQpM315k48IWZ6xOYCU= -github.com/go-ldap/ldap v0.0.0-20240314174501-83a306c8f13f/go.mod h1:/VguTtt2Zcd7XOGAVyeAiwUd5vgfddrM8EzTUsWoQ2k= +github.com/go-asn1-ber/asn1-ber v1.5.7 h1:DTX+lbVTWaTw1hQ+PbZPlnDZPEIs0SS/GCZAl535dDk= +github.com/go-asn1-ber/asn1-ber v1.5.7/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= @@ -43,25 +45,24 @@ github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJA github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= +github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= +github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/tview v0.0.0-20240413115534-b0d41c484b95 h1:dPivHKc1ZAicSlawH/eAmGPSCfOuCYRQLl+Eq1eRKNU= -github.com/rivo/tview v0.0.0-20240413115534-b0d41c484b95/go.mod h1:02iFIz7K/A9jGCvrizLPvoqr4cEIx7q54RH5Qudkrss= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/tview v0.42.0 h1:b/ftp+RxtDsHSaynXTbJb+/n/BxDEi+W3UfF5jILK6c= +github.com/rivo/tview v0.42.0/go.mod h1:cSfIYfhpSGCjp3r/ECJb+GKS7cGJnqV8vfjQPwoXyfY= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= +github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -74,10 +75,10 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= +golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -86,11 +87,11 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= +golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -100,27 +101,27 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= +golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -133,5 +134,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= h12.io/socks v1.0.3 h1:Ka3qaQewws4j4/eDQnOdpr4wXsC//dXtWvftlIcCQUo= h12.io/socks v1.0.3/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck= -software.sslmate.com/src/go-pkcs12 v0.5.0 h1:EC6R394xgENTpZ4RltKydeDUjtlM5drOYIG9c6TVj2M= -software.sslmate.com/src/go-pkcs12 v0.5.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= +software.sslmate.com/src/go-pkcs12 v0.6.0 h1:f3sQittAeF+pao32Vb+mkli+ZyT+VwKaD014qFGq6oU= +software.sslmate.com/src/go-pkcs12 v0.6.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= diff --git a/godap.go b/godap.go index c2933b3..c64b70c 100644 --- a/godap.go +++ b/godap.go @@ -31,7 +31,7 @@ func validateFlagSet(cmd *cobra.Command) error { for _, candidateSet := range acceptableAuthFlagSets { if containsAll(used, candidateSet) { if matches > 0 { - return fmt.Errorf("Invalid authentication flags: mixed flags from multiple acceptable sets\nPlease use only one of {-u,-p},{-u,--passfile},{-u,-H},{-u,--hashfile},{-k},{--crt,--key},{--pfx}\nor none of these for anonymous binds.") + return fmt.Errorf("invalid authentication flags: mixed flags from multiple acceptable sets\nPlease use only one of {-u,-p},{-u,--passfile},{-u,-H},{-u,--hashfile},{-k},{--crt,--key},{--pfx}\nor none of these for anonymous binds") } matches++ } else if intersects(used, candidateSet) { @@ -40,20 +40,12 @@ func validateFlagSet(cmd *cobra.Command) error { } if matches == 0 && partials > 0 { - return fmt.Errorf("Invalid authentication flags: missing required flags\nPlease use only one of {-u,-p},{-u,--passfile},{-u,-H},{-u,--hashfile},{-k},{--crt,--key},{--pfx}\nor none of these for anonymous binds.") + return fmt.Errorf("invalid authentication flags: missing required flags\nPlease use only one of {-u,-p},{-u,--passfile},{-u,-H},{-u,-hashfile},{-k},{--crt,--key},{--pfx}\nor none of these for anonymous binds") } return nil } -func keys(m map[string]bool) []string { - var out []string - for k := range m { - out = append(out, "--"+k) - } - return out -} - func containsAll(provided, required map[string]bool) bool { for k := range required { if !provided[k] { @@ -81,7 +73,7 @@ func main() { err := validateFlagSet(cmd) if err != nil { - log.Fatalf(fmt.Sprint(err)) + log.Fatal(err) } tui.LdapServer = args[0] diff --git a/images/godap.gif b/images/godap.gif old mode 100755 new mode 100644 diff --git a/pkg/adidns/formats.go b/pkg/adidns/formats.go index 0150b04..8140c2b 100644 --- a/pkg/adidns/formats.go +++ b/pkg/adidns/formats.go @@ -3,7 +3,6 @@ package adidns import ( "encoding/binary" "fmt" - "math" "net" "time" ) @@ -30,13 +29,14 @@ func ParseAddrArray(data []byte) []string { family := binary.LittleEndian.Uint16(addrArr[:4]) var ip net.IP - if family == 0x0002 { + switch family { + case 0x0002: // IPv4 ip = net.IP(addrArr[x*32+4 : x*32+8]) - } else if family == 0x0017 { + case 0x0017: // IPv6 ip = net.IP(addrArr[x*32+8 : x*32+24]) - } else { + default: continue } @@ -68,7 +68,7 @@ func ParseIP4Array(data []byte) []string { func FormatHours(val uint64) string { days := 0 if val > 24 { - days = int(math.Floor(float64(val / 24))) + days = int(val / 24) } text := "" diff --git a/pkg/adidns/types.go b/pkg/adidns/types.go index 9b8b240..7ec02a5 100644 --- a/pkg/adidns/types.go +++ b/pkg/adidns/types.go @@ -5,7 +5,6 @@ import ( "encoding/binary" "fmt" "io" - "io/ioutil" "net" "reflect" "strconv" @@ -559,7 +558,10 @@ func ParseCountName(buf *bytes.Reader) (string, error) { } // Consume the NULL terminator - buf.ReadByte() + _, err = buf.ReadByte() + if err != nil { + return "", err + } return strings.Join(labels, "."), nil } @@ -701,7 +703,7 @@ func (rnn *RecordNodeName) Parse(data []byte) { func (rnn *RecordNodeName) Encode() []byte { buf := new(bytes.Buffer) - EncodeCountName(buf, rnn.NameNode) + _ = EncodeCountName(buf, rnn.NameNode) return buf.Bytes() } @@ -759,9 +761,9 @@ func (rs *RecordMailError) Parse(data []byte) { func (rs *RecordMailError) Encode() []byte { buf := new(bytes.Buffer) - EncodeCountName(buf, rs.MailBX) + _ = EncodeCountName(buf, rs.MailBX) - EncodeCountName(buf, rs.ErrorMailBX) + _ = EncodeCountName(buf, rs.ErrorMailBX) return buf.Bytes() } @@ -783,9 +785,9 @@ func (rnp *RecordNamePreference) Parse(data []byte) { func (rnp *RecordNamePreference) Encode() []byte { buf := new(bytes.Buffer) - binary.Write(buf, binary.BigEndian, rnp.Preference) + _ = binary.Write(buf, binary.BigEndian, rnp.Preference) - EncodeCountName(buf, rnp.Exchange) + _ = EncodeCountName(buf, rnp.Exchange) return buf.Bytes() } @@ -884,12 +886,12 @@ func (r *SOARecord) Encode() []byte { fields := []uint32{r.Serial, r.Refresh, r.Retry, r.Expire, r.MinimumTTL} for _, field := range fields { - binary.Write(buf, binary.BigEndian, field) + _ = binary.Write(buf, binary.BigEndian, field) } names := []string{r.NamePrimaryServer, r.ZoneAdminEmail} for _, name := range names { - EncodeCountName(buf, name) + _ = EncodeCountName(buf, name) } return buf.Bytes() @@ -959,24 +961,24 @@ func (r *SIGRecord) Parse(data []byte) { r.NameSigner = parsedName } - sigInfo, _ := ioutil.ReadAll(buf) + sigInfo, _ := io.ReadAll(buf) r.SignatureInfo = sigInfo } func (r *SIGRecord) Encode() []byte { buf := new(bytes.Buffer) - binary.Write(buf, binary.BigEndian, r.TypeCovered) + _ = binary.Write(buf, binary.BigEndian, r.TypeCovered) buf.WriteByte(r.Algorithm) buf.WriteByte(r.Labels) - binary.Write(buf, binary.BigEndian, r.OriginalTTL) - binary.Write(buf, binary.BigEndian, r.SigExpiration) - binary.Write(buf, binary.BigEndian, r.SigInception) - binary.Write(buf, binary.BigEndian, r.KeyTag) + _ = binary.Write(buf, binary.BigEndian, r.OriginalTTL) + _ = binary.Write(buf, binary.BigEndian, r.SigExpiration) + _ = binary.Write(buf, binary.BigEndian, r.SigInception) + _ = binary.Write(buf, binary.BigEndian, r.KeyTag) - EncodeCountName(buf, r.NameSigner) + _ = EncodeCountName(buf, r.NameSigner) buf.Write(r.SignatureInfo) @@ -1076,13 +1078,13 @@ func (r *SRVRecord) Parse(data []byte) { func (r *SRVRecord) Encode() []byte { buf := new(bytes.Buffer) - binary.Write(buf, binary.BigEndian, r.Priority) + _ = binary.Write(buf, binary.BigEndian, r.Priority) - binary.Write(buf, binary.BigEndian, r.Weight) + _ = binary.Write(buf, binary.BigEndian, r.Weight) - binary.Write(buf, binary.BigEndian, r.Port) + _ = binary.Write(buf, binary.BigEndian, r.Port) - EncodeCountName(buf, r.NameTarget) + _ = EncodeCountName(buf, r.NameTarget) return buf.Bytes() } @@ -1151,9 +1153,9 @@ func (r *NAPTRRecord) Parse(data []byte) { func (r *NAPTRRecord) Encode() []byte { buf := new(bytes.Buffer) - binary.Write(buf, binary.BigEndian, r.Order) + _ = binary.Write(buf, binary.BigEndian, r.Order) - binary.Write(buf, binary.BigEndian, r.Preference) + _ = binary.Write(buf, binary.BigEndian, r.Preference) EncodeRpcName(buf, r.Flags) @@ -1161,7 +1163,7 @@ func (r *NAPTRRecord) Encode() []byte { EncodeRpcName(buf, r.Substitution) - EncodeCountName(buf, r.Replacement) + _ = EncodeCountName(buf, r.Replacement) return buf.Bytes() } @@ -1184,7 +1186,7 @@ func (r *DSRecord) Parse(data []byte) { func (r *DSRecord) Encode() []byte { buf := new(bytes.Buffer) - binary.Write(buf, binary.BigEndian, r.KeyTag) + _ = binary.Write(buf, binary.BigEndian, r.KeyTag) buf.WriteByte(r.Algorithm) @@ -1211,15 +1213,15 @@ func (r *NSECRecord) Parse(data []byte) { r.NameSigner = parsedName } - r.NSECBitmap, _ = ioutil.ReadAll(buf) + r.NSECBitmap, _ = io.ReadAll(buf) } func (r *NSECRecord) Encode() []byte { buf := new(bytes.Buffer) - EncodeCountName(buf, r.NameSigner) + _ = EncodeCountName(buf, r.NameSigner) - binary.Write(buf, binary.LittleEndian, r.NSECBitmap) + _ = binary.Write(buf, binary.LittleEndian, r.NSECBitmap) return buf.Bytes() } @@ -1242,7 +1244,7 @@ func (r *DNSKEYRecord) Parse(data []byte) { func (r *DNSKEYRecord) Encode() []byte { buf := new(bytes.Buffer) - binary.Write(buf, binary.BigEndian, r.Flags) + _ = binary.Write(buf, binary.BigEndian, r.Flags) buf.WriteByte(r.Protocol) @@ -1296,7 +1298,7 @@ func (r *NSEC3Record) Encode() []byte { buf.WriteByte(r.Flags) - binary.Write(buf, binary.BigEndian, r.Iterations) + _ = binary.Write(buf, binary.BigEndian, r.Iterations) buf.WriteByte(r.SaltLength) @@ -1335,7 +1337,7 @@ func (r *NSEC3PARAMRecord) Encode() []byte { buf.WriteByte(r.Flags) - binary.Write(buf, binary.BigEndian, r.Iterations) + _ = binary.Write(buf, binary.BigEndian, r.Iterations) buf.WriteByte(r.SaltLength) @@ -1397,16 +1399,17 @@ func (r *WINSRecord) Parse(data []byte) { func (r *WINSRecord) Encode() []byte { buf := new(bytes.Buffer) - binary.Write(buf, binary.BigEndian, r.MappingFlag) + _ = binary.Write(buf, binary.BigEndian, r.MappingFlag) - binary.Write(buf, binary.BigEndian, r.LookupTimeout) + _ = binary.Write(buf, binary.BigEndian, r.LookupTimeout) - binary.Write(buf, binary.BigEndian, r.CacheTimeout) + _ = binary.Write(buf, binary.BigEndian, r.CacheTimeout) - binary.Write(buf, binary.BigEndian, r.WinsSrvCount) + _ = binary.Write(buf, binary.BigEndian, r.WinsSrvCount) for i := uint32(0); i < r.WinsSrvCount; i++ { - binary.Write(buf, binary.BigEndian, r.WinsServers[i]) + ip := net.ParseIP(r.WinsServers[i]) + _ = binary.Write(buf, binary.BigEndian, ip.To4()) } return buf.Bytes() @@ -1434,13 +1437,13 @@ func (r *WINSRRecord) Parse(data []byte) { func (r *WINSRRecord) Encode() []byte { buf := new(bytes.Buffer) - binary.Write(buf, binary.BigEndian, r.MappingFlag) + _ = binary.Write(buf, binary.BigEndian, r.MappingFlag) - binary.Write(buf, binary.BigEndian, r.LookupTimeout) + _ = binary.Write(buf, binary.BigEndian, r.LookupTimeout) - binary.Write(buf, binary.BigEndian, r.CacheTimeout) + _ = binary.Write(buf, binary.BigEndian, r.CacheTimeout) - EncodeCountName(buf, r.NameResultDomain) + _ = EncodeCountName(buf, r.NameResultDomain) return buf.Bytes() } diff --git a/pkg/formats/time.go b/pkg/formats/time.go old mode 100755 new mode 100644 index 493cca0..2bb008d --- a/pkg/formats/time.go +++ b/pkg/formats/time.go @@ -18,50 +18,53 @@ func GetTimeDistString(diff time.Duration) string { days := int(diff.Hours() / 24) var distString string - if days == 0 { + switch days { + case 0: hours := int(diff.Hours()) - if hours == 0 { + switch hours { + case 0: minutes := int(diff.Minutes()) - if minutes == 0 { + switch minutes { + case 0: seconds := int(diff.Seconds()) if future { distString = fmt.Sprintf("(%d seconds from now)", seconds) } else { distString = fmt.Sprintf("(%d seconds ago)", seconds) } - } else if minutes == 1 { + case 1: if future { distString = "(1 minute from now)" } else { distString = "(1 minute ago)" } - } else { + default: if future { distString = fmt.Sprintf("(%d minutes from now)", minutes) } else { distString = fmt.Sprintf("(%d minutes ago)", minutes) } } - } else if hours == 1 { + case 1: if future { distString = "(1 hour from now)" } else { distString = "(1 hour ago)" } - } else { + default: if future { distString = fmt.Sprintf("(%d hours from now)", hours) } else { distString = fmt.Sprintf("(%d hours ago)", hours) } } - } else if days == 1 { + case 1: if future { distString = "(tomorrow)" } else { distString = "(yesterday)" } - } else { + default: if future { distString = fmt.Sprintf("(%d days from now)", days) } else { diff --git a/pkg/ldaputils/actions.go b/pkg/ldaputils/actions.go index 446788e..5b430ad 100644 --- a/pkg/ldaputils/actions.go +++ b/pkg/ldaputils/actions.go @@ -12,8 +12,8 @@ import ( "github.com/Macmod/godap/v2/pkg/adidns" ber "github.com/go-asn1-ber/asn1-ber" - "github.com/go-ldap/ldap/gssapi" "github.com/go-ldap/ldap/v3" + "github.com/go-ldap/ldap/v3/gssapi" "github.com/jcmturner/gokrb5/v8/client" "github.com/jcmturner/gokrb5/v8/config" "github.com/jcmturner/gokrb5/v8/credentials" @@ -65,7 +65,7 @@ func (lc *LDAPConn) GuessFlavor() { func (lc *LDAPConn) UpgradeToTLS(tlsConfig *tls.Config) error { if lc.Conn == nil { - return fmt.Errorf("Current connection is invalid") + return fmt.Errorf("current connection is invalid") } err := lc.Conn.StartTLS(tlsConfig) @@ -78,13 +78,13 @@ func (lc *LDAPConn) UpgradeToTLS(tlsConfig *tls.Config) error { func NewLDAPConn(ldapServer string, ldapPort int, ldaps bool, tlsConfig *tls.Config, pagingSize uint32, rootDN string, proxyConn net.Conn) (*LDAPConn, error) { var conn *ldap.Conn - var err error = nil + var err error if proxyConn == nil { if ldaps { - conn, err = ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort), tlsConfig) + conn, err = ldap.DialURL(fmt.Sprintf("ldaps://%s:%d", ldapServer, ldapPort), ldap.DialWithTLSConfig(tlsConfig)) } else { - conn, err = ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) + conn, err = ldap.DialURL(fmt.Sprintf("ldap://%s:%d", ldapServer, ldapPort)) } } else { if ldaps { @@ -110,7 +110,7 @@ func NewLDAPConn(ldapServer string, ldapPort int, ldaps bool, tlsConfig *tls.Con func (lc *LDAPConn) ExternalBind() error { err := lc.Conn.ExternalBind() if err != nil { - return fmt.Errorf("External bind failed: %v", err) + return fmt.Errorf("external bind failed: %v", err) } return nil @@ -219,7 +219,7 @@ func (lc *LDAPConn) FindNamingContexts() ([]string, error) { } if len(searchResult.Entries) < 1 { - return nil, fmt.Errorf("No entries found") + return nil, fmt.Errorf("no entries found") } for _, x := range searchResult.Entries[0].Attributes { @@ -228,7 +228,7 @@ func (lc *LDAPConn) FindNamingContexts() ([]string, error) { } } - return []string{}, fmt.Errorf("Naming contexts not found") + return []string{}, fmt.Errorf("naming contexts not found") } func (lc *LDAPConn) FindRootDN() (string, error) { @@ -304,7 +304,7 @@ func (lc *LDAPConn) QueryGroupMembersBasic(groupDN string) ([]string, error) { entries := result.Entries if len(entries) != 1 { - return nil, fmt.Errorf("Group '%s' has no members", groupDN) + return nil, fmt.Errorf("group '%s' has no members", groupDN) } var members []string @@ -519,7 +519,7 @@ func (lc *LDAPConn) FindFirst(identifier string) (*ldap.Entry, error) { if len(entries) > 0 { return entries[0], nil } else { - return nil, fmt.Errorf("Object not found") + return nil, fmt.Errorf("object not found") } } @@ -532,7 +532,7 @@ func (lc *LDAPConn) QueryFirst(filter string) (*ldap.Entry, error) { if len(entries) > 0 { return entries[0], nil } else { - return nil, fmt.Errorf("Object not found") + return nil, fmt.Errorf("object not found") } } @@ -816,12 +816,12 @@ func (lc *LDAPConn) GetADIDNSZones(name string, isForest bool) ([]adidns.DNSZone props := make([]adidns.DNSProperty, 0) for _, propStr := range dnsPropsStrs { dnsProp := new(adidns.DNSProperty) - dnsProp.Decode([]byte(propStr)) - - props = append(props, *dnsProp) + if err := dnsProp.Decode([]byte(propStr)); err == nil { + props = append(props, *dnsProp) + } } - zones = append(zones, adidns.DNSZone{zoneDN, zoneName, props}) + zones = append(zones, adidns.DNSZone{DN: zoneDN, Name: zoneName, Props: props}) } return zones, nil @@ -846,14 +846,14 @@ func (lc *LDAPConn) GetADIDNSNode(nodeDN string) (adidns.DNSNode, error) { for _, recordStr := range dnsRecsStrs { dnsRec := new(adidns.DNSRecord) - dnsRec.Decode([]byte(recordStr)) - - records = append(records, *dnsRec) + if err := dnsRec.Decode([]byte(recordStr)); err == nil { + records = append(records, *dnsRec) + } } node.Records = records } else { - return node, fmt.Errorf("Node not found") + return node, fmt.Errorf("node not found") } return node, nil @@ -875,9 +875,9 @@ func (lc *LDAPConn) GetADIDNSNodes(zoneDN string) ([]adidns.DNSNode, error) { for _, recordStr := range dnsRecsStrs { dnsRec := new(adidns.DNSRecord) - dnsRec.Decode([]byte(recordStr)) - - records = append(records, *dnsRec) + if err := dnsRec.Decode([]byte(recordStr)); err == nil { + records = append(records, *dnsRec) + } } nodes = append(nodes, adidns.DNSNode{DN: nodeDN, Name: nodeName, Records: records}) @@ -1077,7 +1077,7 @@ func (lc *LDAPConn) GetSecurityDescriptor(object string) (queryResult string, er return hexSD, nil } - return "", fmt.Errorf("Object '%s' not found", object) + return "", fmt.Errorf("object '%s' not found", object) } func (lc *LDAPConn) FindFirstAttr(filter string, attr string) (string, error) { @@ -1095,7 +1095,7 @@ func (lc *LDAPConn) FindFirstAttr(filter string, attr string) (string, error) { } if len(result.Entries) == 0 { - return "", fmt.Errorf("Search for '%s' returned 0 results", filter) + return "", fmt.Errorf("search for '%s' returned 0 results", filter) } return result.Entries[0].GetAttributeValue(attr), nil @@ -1201,7 +1201,7 @@ func (lc *LDAPConn) FindSamForSID(SID string) (resolvedSID string, err error) { return resolvedSID, nil } - return "", fmt.Errorf("No entries found") + return "", fmt.Errorf("no entries found") } func (lc *LDAPConn) FindPrimaryGroupForSID(SID string) (groupSID string, err error) { @@ -1231,7 +1231,7 @@ func (lc *LDAPConn) FindPrimaryGroupForSID(SID string) (groupSID string, err err } } - return "", fmt.Errorf("No entries found") + return "", fmt.Errorf("no entries found") } func (lc *LDAPConn) FindSchemaControlAccessRights(filter string) (map[string]string, error) { diff --git a/pkg/ldaputils/formats.go b/pkg/ldaputils/formats.go old mode 100755 new mode 100644 index a879475..79fde6a --- a/pkg/ldaputils/formats.go +++ b/pkg/ldaputils/formats.go @@ -80,19 +80,19 @@ func ConvertSID(hexSID string) (SID string) { // TODO: Review correctness of this function func EncodeSID(sid string) (string, error) { if len(sid) < 2 { - return "", fmt.Errorf("Invalid SID format") + return "", fmt.Errorf("invalid SID format") } parts := strings.Split(sid[2:], "-") if len(parts) < 3 { - return "", fmt.Errorf("Invalid SID format") + return "", fmt.Errorf("invalid SID format") } hexSID := "" revision, err := strconv.Atoi(parts[0]) if err != nil { - return "", fmt.Errorf("Error parsing revision: %v", err) + return "", fmt.Errorf("error parsing revision: %v", err) } hexSID += fmt.Sprintf("%02X", revision) @@ -108,7 +108,7 @@ func EncodeSID(sid string) (string, error) { for _, subAuthority := range parts[2:] { subAuthorityValue, err := strconv.Atoi(subAuthority) if err != nil { - return "", fmt.Errorf("Error parsing subauthority: %v", err) + return "", fmt.Errorf("error parsing subauthority: %v", err) } subAuthorityArr := make([]byte, 4) @@ -136,7 +136,7 @@ func ConvertGUID(portion string) string { func EncodeGUID(guid string) (string, error) { tokens := strings.Split(guid, "-") if len(tokens) != 5 { - return "", fmt.Errorf("Wrong GUID format") + return "", fmt.Errorf("wrong GUID format") } result := "" diff --git a/pkg/ldaputils/vars.go b/pkg/ldaputils/vars.go old mode 100755 new mode 100644 diff --git a/pkg/sdl/SDTypeStructures.go b/pkg/sdl/SDTypeStructures.go index f773c63..84a58d3 100644 --- a/pkg/sdl/SDTypeStructures.go +++ b/pkg/sdl/SDTypeStructures.go @@ -26,11 +26,11 @@ func (acl *ACL) Parse(aclStr string) { } var resolvedACEType string - for ace, _ := range rawACESList { + for ace := range rawACESList { aceHeader := newACEHeader(rawACESList[ace]) aceType, _ := strconv.Atoi(aceHeader.ACEType) - for entry, _ := range AceTypeMap { + for entry := range AceTypeMap { if entry == aceType { resolvedACEType = AceTypeMap[entry] } @@ -183,8 +183,7 @@ func (sd *SecurityDescriptor) SetDaclACES(aces []ACEInt) { } func (sd *SecurityDescriptor) Encode() string { - var sdStr string - sdStr = sd.Header.Encode() + sd.SACL.Encode() + sd.DACL.Encode() + sd.Owner + sd.Group + sdStr := sd.Header.Encode() + sd.SACL.Encode() + sd.DACL.Encode() + sd.Owner + sd.Group return sdStr } diff --git a/pkg/sdl/SecurityDescriptorFuncs.go b/pkg/sdl/SecurityDescriptorFuncs.go index 002b6ec..2171f72 100644 --- a/pkg/sdl/SecurityDescriptorFuncs.go +++ b/pkg/sdl/SecurityDescriptorFuncs.go @@ -106,7 +106,7 @@ func AceMaskToText(mask int, guid string) ([]string, int) { return []string{"Full control"}, 3 } - var rightsSeverity int = 0 + var rightsSeverity = 0 var readableRights []string specificChildPermission := combinePerms( diff --git a/tui/ace.go b/tui/ace.go index dd40fe0..856476a 100644 --- a/tui/ace.go +++ b/tui/ace.go @@ -172,7 +172,7 @@ func getFlags(objectGuid string, inheritedGuid string) int { } func createOrUpdateAce(aceIdx int, newAllowOrDeny bool, newACEFlags int, newMask int, newObjectGuid string, newInheritedGuid string, newPrincipalSID string) { - var newACEHeader *sdl.ACEHEADER = new(sdl.ACEHEADER) + var newACEHeader = new(sdl.ACEHEADER) var newACE sdl.ACEInt newACEHeader.ACEType = fmt.Sprintf("%02x", getType(newObjectGuid, newAllowOrDeny)) @@ -204,7 +204,11 @@ func createOrUpdateAce(aceIdx int, newAllowOrDeny bool, newACEFlags int, newMask newACE.SetMask(newMask) // Set ACE Trustee - newACE.SetSID(newPrincipalSID) + err := newACE.SetSID(newPrincipalSID) + if err != nil { + updateLog(fmt.Sprintf("Invalid SID: %s", err), "red") + return + } // Set placeholder ACE size newACEHeader.AceSizeBytes = "0000" @@ -495,9 +499,9 @@ func loadAceEditorForm(aceIdx int) { valMask = aceEntry.Raw.GetMask() newMask = valMask - switch aceRaw.(type) { + switch ace := aceRaw.(type) { case *sdl.OBJECT_ACE: - valObjectGuid, valInheritedGuid = aceRaw.(*sdl.OBJECT_ACE).GetObjectAndInheritedType() + valObjectGuid, valInheritedGuid = ace.GetObjectAndInheritedType() if valObjectGuid != "" { if valMask&0b110000 != 0 { // Property right @@ -508,8 +512,6 @@ func loadAceEditorForm(aceIdx int) { valKind = 1 } else if valMask&0b1000 != 0 { valKind = 4 - } else { - // Should never happen (???) } } } diff --git a/tui/dacl.go b/tui/dacl.go index 6d6af31..c1672c6 100644 --- a/tui/dacl.go +++ b/tui/dacl.go @@ -23,7 +23,7 @@ var ( func parseAces(dst *[]ParsedACE, srcSD *sdl.SecurityDescriptor) { var samAccountName string - var sidMap map[string]string = make(map[string]string) + var sidMap = make(map[string]string) var ok bool for idx, ace := range srcSD.DACL.Aces { @@ -314,11 +314,12 @@ func updateDaclEntries() { readableMask = "Special" } - if entry.Severity == 1 { + switch entry.Severity { + case 1: readableMask = "[purple]" + readableMask - } else if entry.Severity == 2 { + case 2: readableMask = "[blue]" + readableMask - } else if entry.Severity == 3 { + case 3: readableMask = "[red]" + readableMask } diff --git a/tui/dns.go b/tui/dns.go old mode 100755 new mode 100644 index c87eb19..6e5a22f --- a/tui/dns.go +++ b/tui/dns.go @@ -19,7 +19,6 @@ import ( ) var ( - rootDNSNode *tview.TreeNode dnsTreePanel *tview.TreeView dnsQueryPanel *tview.InputField @@ -56,11 +55,11 @@ func getParentZone(objectDN string) (adidns.DNSZone, error) { if zoneOk { return parentZone, nil } else { - return adidns.DNSZone{}, fmt.Errorf("Parent zone not found in the cache") + return adidns.DNSZone{}, fmt.Errorf("parent zone not found in the cache") } } - return adidns.DNSZone{}, fmt.Errorf("Malformed object DN") + return adidns.DNSZone{}, fmt.Errorf("malformed object DN") } func exportADIDNSToFile(currentNode *tview.TreeNode) { @@ -415,11 +414,12 @@ func initADIDNSPage() { switch event.Rune() { case 'r', 'R': go app.QueueUpdateDraw(func() { - if level == 0 { + switch level { + case 0: go queryDnsZones(dnsQueryPanel.GetText()) - } else if level == 1 { + case 1: reloadADIDNSZone(currentNode) - } else if level == 2 { + case 2: reloadADIDNSNode(currentNode) } }) @@ -452,9 +452,10 @@ func initADIDNSPage() { } openDeleteObjectForm(currentNode, func() { - if level == 1 { + switch level { + case 1: go queryDnsZones(dnsQueryPanel.GetText()) - } else if level == 2 { + case 2: pathToCurrent := dnsTreePanel.GetPath(currentNode) if len(pathToCurrent) > 1 { parentNode := pathToCurrent[len(pathToCurrent)-2] @@ -470,17 +471,19 @@ func initADIDNSPage() { if currentNode == dnsTreePanel.GetRoot() { openCreateZoneForm() } else { - if level == 1 { + switch level { + case 1: openCreateNodeForm(currentNode) - } else if level == 2 { + case 2: parentZone := getParentNode(currentNode, dnsTreePanel) openCreateNodeForm(parentZone) } } case tcell.KeyCtrlE: - if level == 1 { + switch level { + case 1: // TODO: Edit zone properties - } else if level == 2 { + case 2: openUpdateNodeForm(currentNode) } } diff --git a/tui/dnsmodify.go b/tui/dnsmodify.go index bd3a9f9..00d8c3e 100644 --- a/tui/dnsmodify.go +++ b/tui/dnsmodify.go @@ -55,12 +55,12 @@ func addZoneHandler(zoneForm *XForm, currentFocus tview.Primitive) func() { // the DNS will synchronize the zone from // Active Directory recSOA := adidns.MakeDNSRecord( - &adidns.SOARecord{1, 900, 600, 86400, 3600, zoneNS, zoneEmail}, + &adidns.SOARecord{Serial: 1, Refresh: 900, Retry: 600, Expire: 86400, MinimumTTL: 3600, NamePrimaryServer: zoneNS, ZoneAdminEmail: zoneEmail}, 0x06, 3600, ) - recNS := adidns.MakeDNSRecord(&adidns.NSRecord{zoneNS}, 0x02, 3600) + recNS := adidns.MakeDNSRecord(&adidns.NSRecord{NameNode: zoneNS}, 0x02, 3600) defaultRecords := []adidns.DNSRecord{ recSOA, @@ -191,9 +191,10 @@ func openActionNodeForm(target *tview.TreeNode, update bool) { var nodeToDelete *tview.TreeNode - if level == 1 { + switch level { + case 1: nodeToDelete = currentNode - } else if level == 2 { + case 2: pathToCurrent := recordsPreview.GetPath(currentNode) if len(pathToCurrent) > 1 { nodeToDelete = pathToCurrent[len(pathToCurrent)-2] @@ -394,10 +395,10 @@ func openActionNodeForm(target *tview.TreeNode, update bool) { if !ok { return } - newNode = adidns.DNSNode{targetDN, node.Name, stagedRecords} + newNode = adidns.DNSNode{DN: targetDN, Name: node.Name, Records: stagedRecords} } else { nodeName := nodeNameInput.GetText() - newNode = adidns.DNSNode{"", nodeName, stagedRecords} + newNode = adidns.DNSNode{DN: "", Name: nodeName, Records: stagedRecords} } // Show preview diff --git a/tui/explorer.go b/tui/explorer.go index 03eb2b1..c4bbdff 100644 --- a/tui/explorer.go +++ b/tui/explorer.go @@ -145,7 +145,10 @@ func reloadParentNode(node *tview.TreeNode) *tview.TreeNode { } func reloadExplorerAttrsPanel(node *tview.TreeNode, useCache bool) { - reloadAttributesPanel(node, explorerAttrsPanel, useCache, &explorerCache) + err := reloadAttributesPanel(node, explorerAttrsPanel, useCache, &explorerCache) + if err != nil { + updateLog(fmt.Sprintf("Error reloading attributes panel: %v", err), "red") + } } func exportCacheToFile(currentNode *tview.TreeNode, cache *EntryCache, fileSuffix string) { @@ -196,7 +199,7 @@ func openUpdateUacForm(node *tview.TreeNode, cache *EntryCache, done func()) { updateUacForm.SetInputCapture(handleEscape(treePanel)) updateUacForm.SetItemPadding(0) - var checkboxState int = 0 + var checkboxState = 0 obj, _ := cache.Get(baseDN) if obj != nil { uacValue, err := strconv.Atoi(obj.GetAttributeValue("userAccountControl")) @@ -312,7 +315,7 @@ func openCreateObjectForm(node *tview.TreeNode, done func()) { case "Computer": err = lc.AddComputer(objectName, baseDN, entryTTLInt) default: - err = fmt.Errorf("Invalid object type") + err = fmt.Errorf("invalid object type") } if err != nil { @@ -413,7 +416,10 @@ func treePanelKeyHandler(event *tcell.EventKey) *tcell.EventKey { updateLog("Reloading node "+baseDN, "yellow") explorerCache.Delete(baseDN) - reloadAttributesPanel(currentNode, explorerAttrsPanel, false, &explorerCache) + err := reloadAttributesPanel(currentNode, explorerAttrsPanel, false, &explorerCache) + if err != nil { + updateLog(fmt.Sprintf("Error reloading attributes panel: %v", err), "red") + } unloadChildren(currentNode) loadChildren(currentNode) diff --git a/tui/group.go b/tui/group.go index fb5e19d..a951850 100644 --- a/tui/group.go +++ b/tui/group.go @@ -238,7 +238,8 @@ func initGroupPage() { }) groupPage = tview.NewFlex().SetDirection(tview.FlexRow) - if lc.Flavor == ldaputils.MicrosoftADFlavor { + switch lc.Flavor { + case ldaputils.MicrosoftADFlavor: groupPage.AddItem(depthInput, 3, 0, false) } @@ -264,7 +265,8 @@ func initGroupPage() { groupDN = queryGroup - if lc.Flavor == ldaputils.MicrosoftADFlavor { + switch lc.Flavor { + case ldaputils.MicrosoftADFlavor: samOrDn, isSam := ldaputils.SamOrDN(queryGroup) if isSam { groupDNQuery := fmt.Sprintf("(&(objectCategory=group)%s)", samOrDn) @@ -278,7 +280,7 @@ func initGroupPage() { } searchGroupMembersAD(groupDN) - } else if lc.Flavor == ldaputils.BasicLDAPFlavor { + case ldaputils.BasicLDAPFlavor: cnUidOrDN, isCnOrUid := ldaputils.CnUidOrDN(queryGroup) if isCnOrUid { groupDNQuery := fmt.Sprintf( diff --git a/tui/main.go b/tui/main.go index 4ee6d22..01330bd 100644 --- a/tui/main.go +++ b/tui/main.go @@ -5,7 +5,6 @@ import ( "crypto/tls" "encoding/json" "fmt" - "io/ioutil" "log" "net" "os" @@ -18,7 +17,6 @@ import ( "github.com/gdamore/tcell/v2" "github.com/go-ldap/ldap/v3" "github.com/rivo/tview" - "golang.org/x/crypto/ssh/terminal" "golang.org/x/term" "h12.io/socks" "software.sslmate.com/src/go-pkcs12" @@ -109,7 +107,7 @@ func readPass(msgIfTerm string) string { var password string - if terminal.IsTerminal(fd) { + if term.IsTerminal(fd) { // Stdin is a terminal fmt.Print(msgIfTerm) passwordBytes, _ := term.ReadPassword(fd) @@ -188,13 +186,14 @@ func toggleFlagD() { func updateSortStateBox(option string) { go app.QueueUpdateDraw(func() { - if option == "none" { + switch option { + case "none": sortAttrsFlagPanel.SetText("OFF") sortAttrsFlagPanel.SetTextColor(tcell.GetColor("red")) - } else if option == "asc" { + case "asc": sortAttrsFlagPanel.SetText("ASC") sortAttrsFlagPanel.SetTextColor(tcell.GetColor("green")) - } else { + default: sortAttrsFlagPanel.SetText("DESC") sortAttrsFlagPanel.SetTextColor(tcell.GetColor("green")) } @@ -202,11 +201,12 @@ func updateSortStateBox(option string) { } func toggleFlagS() { - if AttrSort == "none" { + switch AttrSort { + case "none": AttrSort = "asc" - } else if AttrSort == "asc" { + case "asc": AttrSort = "desc" - } else { + default: AttrSort = "none" } @@ -243,7 +243,7 @@ func writeDataExport(data map[string]any, dumpSuffix string, dumpFormat string) } outputFilepath := filepath.Join(ExportDir, outputFilename) - err = ioutil.WriteFile(outputFilepath, jsonExportMap, 0644) + err = os.WriteFile(outputFilepath, jsonExportMap, 0644) if err != nil { updateLog(fmt.Sprintf("%s", err), "red") @@ -268,7 +268,10 @@ func upgradeStartTLS() { func reconnectLdap() { go app.QueueUpdateDraw(func() { - setupLDAPConn() + err := setupLDAPConn() + if err != nil { + updateLog(fmt.Sprintf("Error reconnecting to LDAP: %v", err), "red") + } }) } @@ -519,7 +522,7 @@ func setupLDAPConn() error { updateLog("Connecting to LDAP server...", "yellow") if lc != nil && lc.Conn != nil { - lc.Conn.Close() + _ = lc.Conn.Close() } tlsConfig = secureTlsConfig @@ -537,9 +540,10 @@ func setupLDAPConn() error { var pw string var hash string - if AuthType == 0 { + switch AuthType { + case 0: currentLdapPassword = strings.TrimSpace(LdapPassword) - } else if AuthType == 1 { + case 1: pw, err = readFileOrStdin(LdapPasswordFile, "Password: ") if err != nil { @@ -547,9 +551,9 @@ func setupLDAPConn() error { log.Fatal(err) } currentLdapPassword = strings.TrimSpace(string(pw)) - } else if AuthType == 2 { + case 2: currentNtlmHash = strings.TrimSpace(NtlmHash) - } else if AuthType == 3 { + case 3: hash, err = readFileOrStdin(NtlmHashFile, "NTLM hash: ") if err != nil { @@ -561,7 +565,8 @@ func setupLDAPConn() error { // If a certificate and key pair is provided, store it // in the TLS config to be used for the connection - if AuthType == 6 { + switch AuthType { + case 6: pfxData, err := os.ReadFile(PfxFile) if err != nil { app.Stop() @@ -582,7 +587,7 @@ func setupLDAPConn() error { } tlsConfig.Certificates = []tls.Certificate{tlsCert} - } else if AuthType == 5 { + case 5: cert, err := tls.LoadX509KeyPair(CertFile, KeyFile) if err != nil { app.Stop() @@ -593,7 +598,7 @@ func setupLDAPConn() error { } var proxyConn net.Conn = nil - var err error = nil + var err error if SocksServer != "" { proxyDial := socks.Dial(SocksServer) @@ -628,7 +633,8 @@ func setupLDAPConn() error { } var bindType string - if AuthType == 5 || AuthType == 6 { + switch AuthType { + case 5, 6: if !Ldaps { // If the connection was not using LDAPS, upgrade it with StartTLS // and then perform an ExternalBind @@ -647,7 +653,7 @@ func setupLDAPConn() error { isSecure = true bindType = "LDAP+ClientCertificate" - } else if AuthType == 4 { + case 4: if _, err := os.Stat(CCachePath); err != nil { app.Stop() log.Fatal(err) @@ -662,10 +668,10 @@ func setupLDAPConn() error { err = lc.KerbBindWithCCache(CCachePath, KdcAddr, DomainName, TargetSpn, "aes") bindType = "Kerberos" - } else if AuthType == 2 || AuthType == 3 { + case 2, 3: err = lc.NTLMBindWithHash(DomainName, LdapUsername, currentNtlmHash) bindType = "NTLM" - } else { + default: currentLdapUsername = LdapUsername if !strings.Contains(LdapUsername, "@") && !strings.Contains(LdapUsername, ",") && LdapUsername != "" && DomainName != "" { currentLdapUsername += "@" + DomainName @@ -800,7 +806,8 @@ func SetupApp() { initHelpPage() var pageVars []GodapPage - if lc.Flavor == ldaputils.MicrosoftADFlavor { + switch lc.Flavor { + case ldaputils.MicrosoftADFlavor: pageVars = []GodapPage{ {0, explorerPage, "Explorer"}, {1, searchPage, "Search"}, @@ -810,7 +817,7 @@ func SetupApp() { {5, dnsPage, "ADIDNS"}, {6, helpPage, "Help"}, } - } else if lc.Flavor == ldaputils.BasicLDAPFlavor { + case ldaputils.BasicLDAPFlavor: pageVars = []GodapPage{ {0, explorerPage, "Explorer"}, {1, searchPage, "Search"}, @@ -841,7 +848,7 @@ func SetupApp() { }) for idx, page := range pageVars { - fmt.Fprintf(info, `%d ["%s"][darkcyan]%s[white][""] `, idx+1, strconv.Itoa(idx), page.title) + _, _ = fmt.Fprintf(info, `%d ["%s"][darkcyan]%s[white][""] `, idx+1, strconv.Itoa(idx), page.title) } info.Highlight("0") diff --git a/tui/search.go b/tui/search.go index a3e87db..6bc0aca 100644 --- a/tui/search.go +++ b/tui/search.go @@ -58,7 +58,10 @@ func addToSearchHistory(query string, duration time.Duration, results int) { var searchLoadedDNs map[string]*tview.TreeNode = make(map[string]*tview.TreeNode) func reloadSearchAttrsPanel(node *tview.TreeNode, useCache bool) { - reloadAttributesPanel(node, searchAttrsPanel, useCache, &searchCache) + err := reloadAttributesPanel(node, searchAttrsPanel, useCache, &searchCache) + if err != nil { + updateLog(fmt.Sprintf("Error reloading attributes panel: %v", err), "red") + } } func reloadSearchNode(currentNode *tview.TreeNode) { @@ -244,10 +247,10 @@ func initSearchPage() { lastDayTimestampStr := strconv.FormatInt(nowTimestamp-86400, 10) lastMonthTimestampStr := strconv.FormatInt(nowTimestamp-2592000, 10) - editedQuery := strings.Replace(ref.(string), "DC=domain,DC=com", lc.DefaultRootDN, -1) - editedQuery = strings.Replace(editedQuery, "", nowTimestampStr, -1) - editedQuery = strings.Replace(editedQuery, "", lastDayTimestampStr, -1) - editedQuery = strings.Replace(editedQuery, "", lastMonthTimestampStr, -1) + editedQuery := strings.ReplaceAll(ref.(string), "DC=domain,DC=com", lc.DefaultRootDN) + editedQuery = strings.ReplaceAll(editedQuery, "", nowTimestampStr) + editedQuery = strings.ReplaceAll(editedQuery, "", lastDayTimestampStr) + editedQuery = strings.ReplaceAll(editedQuery, "", lastMonthTimestampStr) searchQueryPanel.SetText(editedQuery) }, @@ -335,9 +338,9 @@ func initSearchPage() { return event }) - fmt.Fprintf(tabs, `["%s"][white]%s[black][""] `, "0", "Library") - fmt.Fprintf(tabs, `["%s"][white]%s[black][""] `, "1", "Attrs") - fmt.Fprintf(tabs, `["%s"][white]%s[black][""]`, "2", "History") + _, _ = fmt.Fprintf(tabs, `["%s"][white]%s[black][""] `, "0", "Library") + _, _ = fmt.Fprintf(tabs, `["%s"][white]%s[black][""] `, "1", "Attrs") + _, _ = fmt.Fprintf(tabs, `["%s"][white]%s[black][""]`, "2", "History") tabs.SetHighlightedFunc(func(added, removed, remaining []string) { if len(added) > 0 { diff --git a/tui/theme.go b/tui/theme.go index 5567561..4922dac 100644 --- a/tui/theme.go +++ b/tui/theme.go @@ -84,13 +84,6 @@ func assignDropDownTheme(dropdown *tview.DropDown) { dropdown.SetFieldBackgroundColor(DefaultTheme.FieldBackgroundColor) } -func assignFormTheme(form *tview.Form) { - form. - SetButtonBackgroundColor(DefaultTheme.FormButtonBackgroundColor). - SetButtonTextColor(DefaultTheme.FormButtonTextColor). - SetButtonActivatedStyle(DefaultTheme.FormButtonActivatedStyle) -} - // Form customizations type XForm struct { *tview.Form @@ -231,7 +224,7 @@ func GetEntryColor(entry *ldap.Entry) (tcell.Color, bool) { } func GetAttrCellColor(cellName string, cellValue string) (string, bool) { - var color string = "" + var color = "" switch cellName { case "lastLogonTimestamp", "accountExpires", "badPasswordTime", "lastLogoff", "lastLogon", "pwdLastSet", "creationTime", "lockoutTime": diff --git a/tui/tree.go b/tui/tree.go index a4e68cc..fdd6f9f 100644 --- a/tui/tree.go +++ b/tui/tree.go @@ -214,7 +214,9 @@ func handleAttrsKeyCtrlE(currentNode *tview.TreeNode, attrsPanel *tview.Table, c updateLog("Attribute updated: '"+attrNameRef+"' from '"+baseDN+"'", "green") } - reloadAttributesPanel(currentNode, attrsPanel, false, cache) + if err := reloadAttributesPanel(currentNode, attrsPanel, false, cache); err != nil { + updateLog(fmt.Sprintf("Error reloading attributes panel: %v", err), "red") + } /* if parentNode != nil { @@ -260,7 +262,9 @@ func handleAttrsKeyDelete(currentNode *tview.TreeNode, attrsPanel *tview.Table, updateLog(fmt.Sprint(err), "red") } else { cache.Delete(baseDN) - reloadAttributesPanel(currentNode, attrsPanel, false, cache) + if err := reloadAttributesPanel(currentNode, attrsPanel, false, cache); err != nil { + updateLog(fmt.Sprintf("Error reloading attributes panel: %v", err), "red") + } updateLog("Attribute deleted: "+attrName+" from "+baseDN, "green") } @@ -280,7 +284,9 @@ func handleAttrsKeyDelete(currentNode *tview.TreeNode, attrsPanel *tview.Table, updateLog(fmt.Sprint(err), "red") } else { cache.Delete(baseDN) - reloadAttributesPanel(currentNode, attrsPanel, false, cache) + if err := reloadAttributesPanel(currentNode, attrsPanel, false, cache); err != nil { + updateLog(fmt.Sprintf("Error reloading attributes panel: %v", err), "red") + } updateLog("Value deleted: "+attrValue+" from attribute "+attrNameRef, "green") } } @@ -315,7 +321,9 @@ func handleAttrsKeyCtrlN(currentNode *tview.TreeNode, attrsPanel *tview.Table, c updateLog(fmt.Sprint(err), "red") } else { cache.Delete(baseDN) - reloadAttributesPanel(currentNode, attrsPanel, false, cache) + if err := reloadAttributesPanel(currentNode, attrsPanel, false, cache); err != nil { + updateLog(fmt.Sprintf("Error reloading attributes panel: %v", err), "red") + } updateLog("Attribute added: "+attrName+" to "+baseDN, "green") } @@ -422,7 +430,9 @@ func attrsPanelKeyHandler(event *tcell.EventKey, currentNode *tview.TreeNode, ca updateLog("Reloading node "+baseDN, "yellow") cache.Delete(baseDN) - reloadAttributesPanel(currentNode, attrsPanel, false, cache) + if err := reloadAttributesPanel(currentNode, attrsPanel, false, cache); err != nil { + updateLog(fmt.Sprintf("Error reloading attributes panel: %v", err), "red") + } updateLog("Node "+baseDN+" reloaded", "green") @@ -455,7 +465,7 @@ func attrsPanelKeyHandler(event *tcell.EventKey, currentNode *tview.TreeNode, ca func reloadAttributesPanel(node *tview.TreeNode, attrsTable *tview.Table, useCache bool, cache *EntryCache) error { ref := node.GetReference() if ref == nil { - return fmt.Errorf("Couldn't reload attributes: no node selected") + return fmt.Errorf("couldn't reload attributes: no node selected") } var attributes []*ldap.EntryAttribute @@ -469,7 +479,7 @@ func reloadAttributesPanel(node *tview.TreeNode, attrsTable *tview.Table, useCac if ok { attributes = entry.Attributes } else { - return fmt.Errorf("Couldn't reload attributes: node not cached") + return fmt.Errorf("couldn't reload attributes: node not cached") } } else { entries, err := lc.Query(baseDN, SearchFilter, ldap.ScopeBaseObject, Deleted) @@ -479,7 +489,7 @@ func reloadAttributesPanel(node *tview.TreeNode, attrsTable *tview.Table, useCac } if len(entries) != 1 { - return fmt.Errorf("Entry not found") + return fmt.Errorf("entry not found") } entry := entries[0] @@ -494,7 +504,7 @@ func reloadAttributesPanel(node *tview.TreeNode, attrsTable *tview.Table, useCac row := 0 for _, attribute := range attributes { - var cellName string = attribute.Name + var cellName = attribute.Name var cellValues []string @@ -579,11 +589,12 @@ func sortAttributes(attrs []*ldap.EntryAttribute) []*ldap.EntryAttribute { sortedAttrs := make([]*ldap.EntryAttribute, len(attrs)) copy(sortedAttrs, attrs) - if AttrSort == "asc" { + switch AttrSort { + case "asc": sort.Slice(sortedAttrs, func(i, j int) bool { return sortedAttrs[i].Name <= sortedAttrs[j].Name }) - } else if AttrSort == "desc" { + case "desc": sort.Slice(sortedAttrs, func(i, j int) bool { return sortedAttrs[i].Name > sortedAttrs[j].Name })