adap 0.0.16 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +3 -3
- data/lib/adap/adap.rb +54 -17
- data/lib/adap/version.rb +1 -1
- metadata +6 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3158307760aaffe02f99a06d508783b569321759652824029bf91615cdfea9ea
         | 
| 4 | 
            +
              data.tar.gz: 96bf2d0170c919e0a1946d5532c1d9e929dba0003548d6b091ba7d242d3238fd
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: b22800cef66237c05002282ee1b63cc2e6070d151ef899ed67af75a4069b994aeb2f11987b13ff2882864b237fccc8dca9274dba0a35fa25b8da897618dc998e
         | 
| 7 | 
            +
              data.tar.gz: fd5bbdb231aa7c046335c8849af2898c30dd0e564a6b82faab86a4a63a77c8ebd2bd63611c28c8fe5c7ea70bcbad35019ec843497ef54f187051f1034cf2c775
         | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                adap (0.0. | 
| 4 | 
            +
                adap (0.0.16)
         | 
| 5 5 |  | 
| 6 6 | 
             
            GEM
         | 
| 7 7 | 
             
              remote: https://rubygems.org/
         | 
| @@ -9,7 +9,7 @@ GEM | |
| 9 9 | 
             
                minitest (5.14.0)
         | 
| 10 10 | 
             
                mocha (1.11.2)
         | 
| 11 11 | 
             
                net-ldap (0.16.2)
         | 
| 12 | 
            -
                rake ( | 
| 12 | 
            +
                rake (13.0.1)
         | 
| 13 13 | 
             
                unix-crypt (1.3.0)
         | 
| 14 14 |  | 
| 15 15 | 
             
            PLATFORMS
         | 
| @@ -21,7 +21,7 @@ DEPENDENCIES | |
| 21 21 | 
             
              minitest (~> 5.0)
         | 
| 22 22 | 
             
              mocha (~> 1.10)
         | 
| 23 23 | 
             
              net-ldap (~> 0.16.2)
         | 
| 24 | 
            -
              rake (~>  | 
| 24 | 
            +
              rake (~> 13.0)
         | 
| 25 25 | 
             
              unix-crypt (~> 1.3)
         | 
| 26 26 |  | 
| 27 27 | 
             
            BUNDLED WITH
         | 
    
        data/lib/adap/adap.rb
    CHANGED
    
    | @@ -24,9 +24,18 @@ class Adap | |
| 24 24 | 
             
                }
         | 
| 25 25 |  | 
| 26 26 | 
             
                # List of attributes for user in AD
         | 
| 27 | 
            -
                @ad_user_required_attributes   = [:cn, :sn, :uid, :uidnumber, :gidnumber, :displayname, :loginshell, :gecos, :givenname, :unixhomedirectory]
         | 
| 27 | 
            +
                @ad_user_required_attributes   = [:cn, :sn, :uid, :uidnumber, :gidnumber, :displayname, :loginshell, :gecos, :givenname, :description, :mail, :unixhomedirectory]
         | 
| 28 28 | 
             
                # List of attributes for user in LDAP
         | 
| 29 | 
            -
                @ldap_user_required_attributes = [:cn, :sn, :uid, :uidnumber, :gidnumber, :displayname, :loginshell, :gecos, :givenname, :homedirectory]
         | 
| 29 | 
            +
                @ldap_user_required_attributes = [:cn, :sn, :uid, :uidnumber, :gidnumber, :displayname, :loginshell, :gecos, :givenname, :description, :mail, :homedirectory]
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                # List of supported hash algorithms keys and string values to operate
         | 
| 32 | 
            +
                @supported_hash_algorithms_map = {
         | 
| 33 | 
            +
                  :md5                  => "{MD5}",
         | 
| 34 | 
            +
                  :sha                  => "{SHA}",
         | 
| 35 | 
            +
                  :ssha                 => "{SSHA}",
         | 
| 36 | 
            +
                  :virtual_crypt_sha256 => "virtualCryptSHA256",
         | 
| 37 | 
            +
                  :virtual_crypt_sha512 => "virtualCryptSHA512"
         | 
| 38 | 
            +
                }
         | 
| 30 39 |  | 
| 31 40 | 
             
                @ad_host                  = params[:ad_host]
         | 
| 32 41 | 
             
                @ad_port                  = (params[:ad_port] ? params[:ad_port] : 389)
         | 
| @@ -40,8 +49,17 @@ class Adap | |
| 40 49 | 
             
                @ldap_basedn              = params[:ldap_basedn]
         | 
| 41 50 | 
             
                @ldap_user_basedn         = params[:ldap_user_basedn]
         | 
| 42 51 | 
             
                @ldap_auth                = (params.has_key?(:ldap_password) ? { :method => :simple, :username => @ldap_binddn, :password => params[:ldap_password] } : nil )
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                 | 
| 52 | 
            +
             | 
| 53 | 
            +
                # A password-hash algorithm to sync to the LDAP.
         | 
| 54 | 
            +
                # Popular LDAP products like Open LDAP usually supports md5({MD5}), sha1({SHA}) and ssha({SSHA}) algorithms.
         | 
| 55 | 
            +
                # If you want to use virtualCryptSHA256 or virtualCryptSHA512, you have to set additional configurations to OpenLDAP.
         | 
| 56 | 
            +
                @password_hash_algorithm  = (params[:password_hash_algorithm] ? params[:password_hash_algorithm] : :ssha)
         | 
| 57 | 
            +
                # TODO: Check a hash algorithm is supported or not
         | 
| 58 | 
            +
                unless @supported_hash_algorithms_map.has_key?(@password_hash_algorithm) then
         | 
| 59 | 
            +
                  raise "This program only supports :md5, :sha, :ssha(default), :virtual_crypt_sha256 and :virtual_crypt_sha512 " \
         | 
| 60 | 
            +
                        + "as :password_hash_algorithm. " \
         | 
| 61 | 
            +
                        + "An algorithm you chose #{@password_hash_algorithm.is_a?(Symbol) ? ":" : ""}#{@password_hash_algorithm} was unsupported."
         | 
| 62 | 
            +
                end
         | 
| 45 63 |  | 
| 46 64 | 
             
                # Phonetics are listed in https://lists.samba.org/archive/samba/2017-March/207308.html
         | 
| 47 65 | 
             
                @map_ad_msds_phonetics = {}
         | 
| @@ -112,22 +130,33 @@ class Adap | |
| 112 130 | 
             
                attributes
         | 
| 113 131 | 
             
              end
         | 
| 114 132 |  | 
| 115 | 
            -
              def  | 
| 116 | 
            -
                 | 
| 133 | 
            +
              def get_password_hash(username, password)
         | 
| 134 | 
            +
                case @password_hash_algorithm
         | 
| 135 | 
            +
                when :md5, :sha, :ssha then
         | 
| 136 | 
            +
                  if password.nil? then
         | 
| 137 | 
            +
                    raise "Password must not be nil when you chose the algorithm of password-hash is :md5 or :sha or :ssha. Pass password of #{username} please."
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
                  result = Net::LDAP::Password.generate(@password_hash_algorithm, password)
         | 
| 140 | 
            +
                else
         | 
| 141 | 
            +
                  # Expects :virtual_crypt_sha256(virtualCryptSHA256) or :virtual_crypt_sha512(virtualCryptSHA512)
         | 
| 142 | 
            +
                  result = get_raw_password_from_ad(username, @supported_hash_algorithms_map[@password_hash_algorithm])
         | 
| 143 | 
            +
                end
         | 
| 117 144 |  | 
| 118 | 
            -
                if  | 
| 119 | 
            -
                  raise "Failed to get password of #{username} | 
| 145 | 
            +
                if result.nil? or result.empty? then
         | 
| 146 | 
            +
                  raise "Failed to get hashed password with algorithm :#{@password_hash_algorithm} of user #{username}. " +
         | 
| 147 | 
            +
                    "Its result was nil. If you chose hash-algorithm :virtual_crypt_sha256 or :virtual_crypt_sha512, " +
         | 
| 148 | 
            +
                    "did you enabled AD to store passwords as virtualCryptSHA256 and/or virtualCryptSHA512 in your smb.conf? " +
         | 
| 149 | 
            +
                    "This program requires the configuration to get password from AD as virtualCryptSHA256 or virtualCryptSHA512."
         | 
| 120 150 | 
             
                end
         | 
| 121 | 
            -
                password = password.chomp
         | 
| 122 151 |  | 
| 123 | 
            -
                 | 
| 152 | 
            +
                result.chomp
         | 
| 124 153 | 
             
              end
         | 
| 125 154 |  | 
| 126 | 
            -
              def  | 
| 155 | 
            +
              def get_raw_password_from_ad(username, algo)
         | 
| 127 156 | 
             
                `samba-tool user getpassword #{username} --attribute #{algo} 2> /dev/null | grep -E '^virtualCrypt' -A 1 | tr -d ' \n' | cut -d ':' -f 2`
         | 
| 128 157 | 
             
              end
         | 
| 129 158 |  | 
| 130 | 
            -
              def sync_user(uid)
         | 
| 159 | 
            +
              def sync_user(uid, password=nil)
         | 
| 131 160 | 
             
                ad_entry    = nil
         | 
| 132 161 | 
             
                ldap_entry  = nil
         | 
| 133 162 | 
             
                ad_dn       = get_ad_dn(uid)
         | 
| @@ -139,6 +168,7 @@ class Adap | |
| 139 168 | 
             
                end
         | 
| 140 169 | 
             
                ret_code = @ad_client.get_operation_result.code
         | 
| 141 170 |  | 
| 171 | 
            +
                # Return 32 means that the object does not exist
         | 
| 142 172 | 
             
                return {
         | 
| 143 173 | 
             
                  :code => ret_code,
         | 
| 144 174 | 
             
                  :operations => nil,
         | 
| @@ -158,11 +188,11 @@ class Adap | |
| 158 188 |  | 
| 159 189 | 
             
                ret = nil
         | 
| 160 190 | 
             
                if !ad_entry.nil? and ldap_entry.nil? then
         | 
| 161 | 
            -
                  ret = add_user(ldap_dn, ad_entry,  | 
| 191 | 
            +
                  ret = add_user(ldap_dn, ad_entry, get_password_hash(uid, password))
         | 
| 162 192 | 
             
                elsif ad_entry.nil? and !ldap_entry.nil? then
         | 
| 163 193 | 
             
                  ret = delete_user(ldap_dn)
         | 
| 164 194 | 
             
                elsif !ad_entry.nil? and !ldap_entry.nil? then
         | 
| 165 | 
            -
                  ret = modify_user(ldap_dn, ad_entry, ldap_entry,  | 
| 195 | 
            +
                  ret = modify_user(ldap_dn, ad_entry, ldap_entry, get_password_hash(uid, password))
         | 
| 166 196 | 
             
                else
         | 
| 167 197 | 
             
                  # ad_entry.nil? and ldap_entry.nil? then
         | 
| 168 198 | 
             
                  return {:code => 0, :operations => nil, :message => "There are not any data of #{uid} to sync."}
         | 
| @@ -184,6 +214,10 @@ class Adap | |
| 184 214 | 
             
              end
         | 
| 185 215 |  | 
| 186 216 | 
             
              def add_user(ldap_user_dn, ad_entry, password)
         | 
| 217 | 
            +
                if password == nil || password.empty?
         | 
| 218 | 
            +
                  raise "add_user() requires password. Set a hashed password of the user #{ad_entry[:cn]} please."
         | 
| 219 | 
            +
                end
         | 
| 220 | 
            +
             | 
| 187 221 | 
             
                attributes = create_ldap_attributes(ad_entry)
         | 
| 188 222 |  | 
| 189 223 | 
             
                @ldap_client.add(
         | 
| @@ -209,7 +243,7 @@ class Adap | |
| 209 243 | 
             
                return {
         | 
| 210 244 | 
             
                  :code => ret_code,
         | 
| 211 245 | 
             
                  :operations => [:add_user],
         | 
| 212 | 
            -
                  :message => "Failed to modify a user #{ldap_user_dn} in add_user() - " + @ldap_client.get_operation_result.error_message
         | 
| 246 | 
            +
                  :message => "Failed to modify a user #{ldap_user_dn} to add userPassword in add_user() - " + @ldap_client.get_operation_result.error_message
         | 
| 213 247 | 
             
                } if ret_code != 0
         | 
| 214 248 |  | 
| 215 249 | 
             
                return {:code => ret_code, :operations => [:add_user], :message => nil}
         | 
| @@ -273,7 +307,9 @@ class Adap | |
| 273 307 |  | 
| 274 308 | 
             
                # AD does not have password as simple ldap attribute.
         | 
| 275 309 | 
             
                # So password will always be updated for this reason.
         | 
| 276 | 
            -
                 | 
| 310 | 
            +
                if not password.nil? and not password.empty? then
         | 
| 311 | 
            +
                  operations.push([:replace, :userpassword, password])
         | 
| 312 | 
            +
                end
         | 
| 277 313 |  | 
| 278 314 | 
             
                operations
         | 
| 279 315 | 
             
              end
         | 
| @@ -502,12 +538,13 @@ class Adap | |
| 502 538 |  | 
| 503 539 | 
             
              def get_primary_gidnumber_from_ad(uid)
         | 
| 504 540 | 
             
                return nil if uid ==nil
         | 
| 541 | 
            +
                primary_gid = nil
         | 
| 505 542 |  | 
| 506 543 | 
             
                @ad_client.search(:base => "CN=#{uid},CN=Users,#{@ad_basedn}") do |entry|
         | 
| 507 544 | 
             
                  primary_gid = entry[:gidnumber].first
         | 
| 508 545 | 
             
                end
         | 
| 509 546 |  | 
| 510 | 
            -
                 | 
| 547 | 
            +
                primary_gid
         | 
| 511 548 | 
             
              end
         | 
| 512 549 |  | 
| 513 550 | 
             
            end
         | 
    
        data/lib/adap/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: adap
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0 | 
| 4 | 
            +
              version: 0.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Tsutomu Nakamura
         | 
| 8 | 
            -
            autorequire: | 
| 8 | 
            +
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2020- | 
| 11 | 
            +
            date: 2020-08-01 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -79,7 +79,7 @@ homepage: https://github.com/TsutomuNakamura/adap | |
| 79 79 | 
             
            licenses: []
         | 
| 80 80 | 
             
            metadata:
         | 
| 81 81 | 
             
              homepage_uri: https://github.com/TsutomuNakamura/adap
         | 
| 82 | 
            -
            post_install_message: | 
| 82 | 
            +
            post_install_message:
         | 
| 83 83 | 
             
            rdoc_options: []
         | 
| 84 84 | 
             
            require_paths:
         | 
| 85 85 | 
             
            - lib
         | 
| @@ -94,8 +94,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 94 94 | 
             
                - !ruby/object:Gem::Version
         | 
| 95 95 | 
             
                  version: '0'
         | 
| 96 96 | 
             
            requirements: []
         | 
| 97 | 
            -
            rubygems_version: 3.1. | 
| 98 | 
            -
            signing_key: | 
| 97 | 
            +
            rubygems_version: 3.1.3
         | 
| 98 | 
            +
            signing_key:
         | 
| 99 99 | 
             
            specification_version: 4
         | 
| 100 100 | 
             
            summary: LDAP migration tool from AD to NT schema
         | 
| 101 101 | 
             
            test_files: []
         |