pwp_test.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. """
  2. # --- BEGIN COPYRIGHT BLOCK ---
  3. # Copyright (C) 2020 Red Hat, Inc.
  4. # All rights reserved.
  5. #
  6. # License: GPL (version 3 or any later version).
  7. # See LICENSE for details.
  8. # --- END COPYRIGHT BLOCK ---
  9. """
  10. import os
  11. import pytest
  12. from lib389.topologies import topology_st as topo
  13. from lib389.idm.user import UserAccounts, UserAccount
  14. from lib389._constants import DEFAULT_SUFFIX
  15. from lib389.config import Config
  16. from lib389.idm.group import Group
  17. from lib389.utils import ds_is_older
  18. import ldap
  19. import time
  20. pytestmark = pytest.mark.tier1
  21. if ds_is_older('1.4'):
  22. DEFAULT_PASSWORD_STORAGE_SCHEME = 'SSHA512'
  23. else:
  24. DEFAULT_PASSWORD_STORAGE_SCHEME = 'PBKDF2_SHA256'
  25. def _create_user(topo, uid, cn, uidNumber, userpassword):
  26. """
  27. Will Create user
  28. """
  29. user = UserAccounts(topo.standalone, DEFAULT_SUFFIX).create(properties={
  30. 'uid': uid,
  31. 'sn': cn.split(' ')[-1],
  32. 'cn': cn,
  33. 'givenname': cn.split(' ')[0],
  34. 'uidNumber': uidNumber,
  35. 'gidNumber': uidNumber,
  36. 'mail': f'{uid}@example.com',
  37. 'userpassword': userpassword,
  38. 'homeDirectory': f'/home/{uid}'
  39. })
  40. return user
  41. def _change_password_with_own(topo, user_dn, password, new_password):
  42. """
  43. Change user password with user self
  44. """
  45. conn = UserAccount(topo.standalone, user_dn).bind(password)
  46. real_user = UserAccount(conn, user_dn)
  47. real_user.replace('userpassword', new_password)
  48. def _change_password_with_root(topo, user_dn, new_password):
  49. """
  50. Root will change user password
  51. """
  52. UserAccount(topo.standalone, user_dn).replace('userpassword', new_password)
  53. @pytest.fixture(scope="function")
  54. def _fix_password(topo, request):
  55. user = _create_user(topo, 'dbyers', 'Danny Byers', '1001', 'dbyers1')
  56. user.replace('userpassword', 'dbyers1')
  57. def fin():
  58. user.delete()
  59. request.addfinalizer(fin)
  60. def test_passwordchange_to_no(topo, _fix_password):
  61. """Change password fo a user even password even though pw policy is set to no
  62. :id: 16c64ef0-5a20-11ea-a902-8c16451d917b
  63. :setup: Standalone
  64. :steps:
  65. 1. Adding an user with uid=dbyers
  66. 2. Set Password change to Must Not Change After Reset
  67. 3. Setting Password policy to May Not Change Password
  68. 4. Try to change password fo a user even password even though pw policy is set to no
  69. 5. Set Password change to May Change Password
  70. 6. Try to change password fo a user even password
  71. 7. Try to change password with invalid credentials. Should see error message.
  72. :expected results:
  73. 1. Success
  74. 2. Success
  75. 3. Success
  76. 4. Success
  77. 5. Success
  78. 6. Success
  79. 7. Success
  80. """
  81. # Adding an user with uid=dbyers
  82. user = f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}'
  83. config = Config(topo.standalone)
  84. # Set Password change to Must Not Change After Reset
  85. config.replace_many(
  86. ('passwordmustchange', 'off'),
  87. ('passwordchange', 'off'))
  88. # Try to change password fo a user even password even though pw policy is set to no
  89. with pytest.raises(ldap.UNWILLING_TO_PERFORM):
  90. _change_password_with_own(topo, user, 'dbyers1', 'AB')
  91. # Set Password change to May Change Password
  92. config.replace('passwordchange', 'on')
  93. _change_password_with_own(topo, user, 'dbyers1', 'dbyers1')
  94. # Try to change password with invalid credentials. Should see error message.
  95. with pytest.raises(ldap.INVALID_CREDENTIALS):
  96. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'AB', 'dbyers1')
  97. def test_password_check_syntax(topo, _fix_password):
  98. """Password check syntax
  99. :id: 1e6fcc9e-5a20-11ea-9659-8c16451d917b
  100. :setup: Standalone
  101. :steps:
  102. 1. Sets Password check syntax to on
  103. 2. Try to change to a password that violates length. Should get error
  104. 3. Attempt to Modify password to db which is in error to policy
  105. 4. change min pw length to 5
  106. 5. Attempt to Modify password to dby3rs which is in error to policy
  107. 6. Attempt to Modify password to danny which is in error to policy
  108. 7. Attempt to Modify password to byers which is in error to policy
  109. 8. Change min pw length to 6
  110. 9. Try to change the password
  111. 10. Trying to set to a password containing value of sn
  112. 11. Sets policy to not check pw syntax
  113. 12. Test that when checking syntax is off, you can use small passwords
  114. 13. Test that when checking syntax is off, trivial passwords can be used
  115. 14. Changing password minimum length from 6 to 10
  116. 15. Setting policy to Check Password Syntax again
  117. 16. Try to change to a password that violates length
  118. 17. Reset Password
  119. :expected results:
  120. 1. Success
  121. 2. Success
  122. 3. Success
  123. 4. Success
  124. 5. Success
  125. 6. Success
  126. 7. Success
  127. 8. Success
  128. 9. Success
  129. 10. Success
  130. 11. Success
  131. 12. Success
  132. 13. Success
  133. 14. Success
  134. 15. Success
  135. 16. Fail
  136. 17. Success
  137. """
  138. config = Config(topo.standalone)
  139. # Sets Password check syntax to on
  140. config.replace('passwordchecksyntax', 'on')
  141. # Try to change to a password that violates length. Should get error
  142. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  143. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers2')
  144. # Attempt to Modify password to db which is in error to policy
  145. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  146. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'db')
  147. # change min pw length to 5
  148. config.replace('passwordminlength', '5')
  149. # Attempt to Modify password to dby3rs which is in error to policy
  150. # Attempt to Modify password to danny which is in error to policy
  151. # Attempt to Modify password to byers which is in error to policy
  152. for password in ['dbyers', 'Danny', 'byers']:
  153. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  154. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', password)
  155. # Change min pw length to 6
  156. config.replace('passwordminlength', '6')
  157. # Try to change the password
  158. # Trying to set to a password containing value of sn
  159. for password in ['dby3rs1', 'dbyers2', '67Danny89', 'YAByers8']:
  160. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  161. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', password)
  162. # Sets policy to not check pw syntax
  163. # Test that when checking syntax is off, you can use small passwords
  164. # Test that when checking syntax is off, trivial passwords can be used
  165. config.replace('passwordchecksyntax', 'off')
  166. for password, new_pass in [('dbyers1', 'db'), ('db', 'dbyers'), ('dbyers', 'dbyers1')]:
  167. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', password, new_pass)
  168. # Changing password minimum length from 6 to 10
  169. # Setting policy to Check Password Syntax again
  170. config.replace_many(
  171. ('passwordminlength', '10'),
  172. ('passwordchecksyntax', 'on'))
  173. # Try to change to a password that violates length
  174. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  175. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'db')
  176. UserAccount(topo.standalone, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}').replace('userpassword', 'dbyers1')
  177. def test_too_big_password(topo, _fix_password):
  178. """Test for long long password
  179. :id: 299a3fb4-5a20-11ea-bba8-8c16451d917b
  180. :setup: Standalone
  181. :steps:
  182. 1. Setting policy to keep password histories
  183. 2. Changing number of password in history to 3
  184. 3. Modify password from dby3rs1 to dby3rs2
  185. 4. Checking that the passwordhistory attribute has been added
  186. 5. Add a password test for long long password
  187. 6. Changing number of password in history to 6 and passwordhistory off
  188. :expected results:
  189. 1. Success
  190. 2. Success
  191. 3. Success
  192. 4. Success
  193. 5. Success
  194. 6. Success
  195. """
  196. config = Config(topo.standalone)
  197. # Setting policy to keep password histories
  198. config.replace_many(
  199. ('passwordchecksyntax', 'off'),
  200. ('passwordhistory', 'on'))
  201. assert config.get_attr_val_utf8('passwordinhistory') == '6'
  202. # Changing number of password in history to 3
  203. config.replace('passwordinhistory', '3')
  204. # Modify password from dby3rs1 to dby3rs2
  205. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers2')
  206. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  207. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers2', 'dbyers1')
  208. # Checking that the passwordhistory attribute has been added
  209. assert UserAccount(topo.standalone, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}').get_attr_val_utf8('passwordhistory')
  210. # Add a password test for long long password
  211. long_pass = 50*'0123456789'+'LENGTH=510'
  212. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers2', long_pass)
  213. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  214. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', long_pass, long_pass)
  215. _change_password_with_root(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1')
  216. # Changing number of password in history to 6 and passwordhistory off
  217. config.replace_many(('passwordhistory', 'off'),
  218. ('passwordinhistory', '6'))
  219. def test_pwminage(topo, _fix_password):
  220. """Test pwminage
  221. :id: 2df7bf32-5a20-11ea-ad23-8c16451d917b
  222. :setup: Standalone
  223. :steps:
  224. 1. Get pwminage; should be 0 currently
  225. 2. Sets policy to pwminage 3
  226. 3. Change current password
  227. 4. Try to change password again
  228. 5. Try now after 3 secs is up, should work.
  229. :expected results:
  230. 1. Success
  231. 2. Success
  232. 3. Success
  233. 4. Fail
  234. 5. Success
  235. """
  236. config = Config(topo.standalone)
  237. # Get pwminage; should be 0 currently
  238. assert config.get_attr_val_utf8('passwordminage') == '0'
  239. # Sets policy to pwminage 3
  240. config.replace('passwordminage', '3')
  241. # Change current password
  242. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers2')
  243. # Try to change password again
  244. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  245. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers2', 'dbyers1')
  246. for _ in range(3):
  247. time.sleep(1)
  248. # Try now after 3 secs is up, should work.
  249. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers2', 'dbyers1')
  250. config.replace('passwordminage', '0')
  251. def test_invalid_credentials(topo, _fix_password):
  252. """Test bind again with valid password: We should be locked
  253. :id: 3233ca78-5a20-11ea-8d35-8c16451d917b
  254. :setup: Standalone
  255. :steps:
  256. 1. Search if passwordlockout is off
  257. 2. Turns on passwordlockout
  258. 3. sets lockout duration to 3 seconds
  259. 4. Changing pw failure count reset duration to 3 sec and passwordminlength to 10
  260. 5. Try to bind with invalid credentials
  261. 6. Change password to password lockout forever
  262. 7. Try to bind with invalid credentials
  263. 8. Now bind again with valid password: We should be locked
  264. 9. Delete dby3rs before exiting
  265. 10. Reset server
  266. :expected results:
  267. 1. Success
  268. 2. Success
  269. 3. Success
  270. 4. Success
  271. 5. Fail
  272. 6. Success
  273. 7. Success
  274. 8. Success
  275. 9. Success
  276. 10. Success
  277. """
  278. config = Config(topo.standalone)
  279. # Search if passwordlockout is off
  280. assert config.get_attr_val_utf8('passwordlockout') == 'off'
  281. # Turns on passwordlockout
  282. # sets lockout duration to 3 seconds
  283. # Changing pw failure count reset duration to 3 sec and passwordminlength to 10
  284. config.replace_many(
  285. ('passwordlockout', 'on'),
  286. ('passwordlockoutduration', '3'),
  287. ('passwordresetfailurecount', '3'),
  288. ('passwordminlength', '10'))
  289. # Try to bind with invalid credentials
  290. for _ in range(3):
  291. with pytest.raises(ldap.INVALID_CREDENTIALS):
  292. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'Invalid', 'dbyers1')
  293. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  294. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'Invalid', 'dbyers1')
  295. for _ in range(3):
  296. time.sleep(1)
  297. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers1')
  298. # Change password to password lockout forever
  299. config.replace('passwordunlock', 'off')
  300. # Try to bind with invalid credentials
  301. for _ in range(3):
  302. with pytest.raises(ldap.INVALID_CREDENTIALS):
  303. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'Invalid', 'dbyers1')
  304. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  305. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'Invalid', 'dbyers1')
  306. for _ in range(3):
  307. time.sleep(1)
  308. # Now bind again with valid password: We should be locked
  309. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  310. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers1')
  311. # Delete dby3rs before exiting
  312. _change_password_with_root(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1')
  313. time.sleep(1)
  314. _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers1')
  315. # Reset server
  316. config.replace_many(
  317. ('passwordinhistory', '6'),
  318. ('passwordlockout', 'off'),
  319. ('passwordlockoutduration', '3600'),
  320. ('passwordminlength', '6'),
  321. ('passwordresetfailurecount', '600'),
  322. ('passwordunlock', 'on'))
  323. def test_expiration_date(topo, _fix_password):
  324. """Test check the expiration date is still in the future
  325. :id: 3691739a-5a20-11ea-8712-8c16451d917b
  326. :setup: Standalone
  327. :steps:
  328. 1. Password expiration
  329. 2. Add a user with a password expiration date
  330. 3. Modify their password
  331. 4. Check the expiration date is still in the future
  332. 5. Modify the password expiration date
  333. 6. Check the expiration date is still in the future
  334. 7. Change policy so that user can change passwords
  335. 8. Deleting user
  336. 9. Adding user
  337. 10. Set password history ON
  338. 11. Modify password Once
  339. 12. Try to change the password with same one
  340. :expected results:
  341. 1. Success
  342. 2. Success
  343. 3. Success
  344. 4. Success
  345. 5. Success
  346. 6. Success
  347. 7. Success
  348. 8. Success
  349. 9. Success
  350. 10. Success
  351. 11. Success
  352. 12. Fail
  353. """
  354. # Add a user with a password expiration date
  355. user = UserAccounts(topo.standalone, DEFAULT_SUFFIX).create_test_user()
  356. user.replace_many(
  357. ('userpassword', 'bind4now'),
  358. ('passwordExpirationTime', '20380119031404Z'))
  359. # Modify their password
  360. user.replace('userPassword', 'secreter')
  361. # Check the expiration date is still in the future
  362. assert user.get_attr_val_utf8('passwordExpirationTime') == '20380119031404Z'
  363. # Modify the password expiration date
  364. user.replace('passwordExpirationTime', '20380119031405Z')
  365. # Check the expiration date is still in the future
  366. assert user.get_attr_val_utf8('passwordExpirationTime') == '20380119031405Z'
  367. config = Config(topo.standalone)
  368. # Change policy so that user can change passwords
  369. config.replace('passwordchange', 'on')
  370. # Deleting user
  371. UserAccount(topo.standalone, f'uid=test_user_1000,ou=People,{DEFAULT_SUFFIX}').delete()
  372. # Adding user
  373. user = UserAccounts(topo.standalone, DEFAULT_SUFFIX).create_test_user()
  374. # Set password history ON
  375. config.replace('passwordhistory', 'on')
  376. # Modify password Once
  377. user.replace('userPassword', 'secreter')
  378. time.sleep(1)
  379. assert DEFAULT_PASSWORD_STORAGE_SCHEME in user.get_attr_val_utf8('userPassword')
  380. # Try to change the password with same one
  381. for _ in range(3):
  382. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  383. _change_password_with_own(topo, user.dn, 'secreter', 'secreter')
  384. user.delete()
  385. def test_passwordlockout(topo, _fix_password):
  386. """Test adding admin user diradmin to Directory Administrator group
  387. :id: 3ffcffda-5a20-11ea-a3af-8c16451d917b
  388. :setup: Standalone
  389. :steps:
  390. 1. Account Lockout must be cleared on successful password change
  391. 2. Adding admin user diradmin
  392. 3. Adding admin user diradmin to Directory Administrator group
  393. 4. Turn on passwordlockout
  394. 5. Sets lockout duration to 30 seconds
  395. 6. Sets failure count reset duration to 30 sec
  396. 7. Sets max password bind failure count to 3
  397. 8. Reset password retry count (to 0)
  398. 9. Try to bind with invalid credentials(3 times)
  399. 10. Try to bind with valid pw, should give lockout error
  400. 11. Reset password using admin login
  401. 12. Try to login as the user to check the unlocking of account. Will also change
  402. the password back to original
  403. 13. Change to account lockout forever until reset
  404. 14. Reset password retry count (to 0)
  405. 15. Try to bind with invalid credentials(3 times)
  406. 16. Try to bind with valid pw, should give lockout error
  407. 17. Reset password using admin login
  408. 18. Try to login as the user to check the unlocking of account. Will also change the
  409. password back to original
  410. :expected results:
  411. 1. Success
  412. 2. Success
  413. 3. Success
  414. 4. Success
  415. 5. Success
  416. 6. Success
  417. 7. Success
  418. 8. Success
  419. 9. Fail
  420. 10. Success
  421. 11. Success
  422. 12. Success
  423. 13. Success
  424. 14. Success
  425. 15. Fail
  426. 16. Success
  427. 17. Success
  428. 18. Success
  429. """
  430. config = Config(topo.standalone)
  431. # Adding admin user diradmin
  432. user = UserAccounts(topo.standalone, DEFAULT_SUFFIX).create_test_user()
  433. user.replace('userpassword', 'dby3rs2')
  434. admin = _create_user(topo, 'diradmin', 'Anuj Borah', '1002', 'diradmin')
  435. # Adding admin user diradmin to Directory Administrator group
  436. Group(topo.standalone, f'cn=user_passwd_reset,ou=permissions,{DEFAULT_SUFFIX}').add('member', admin.dn)
  437. # Turn on passwordlockout
  438. # Sets lockout duration to 30 seconds
  439. # Sets failure count reset duration to 30 sec
  440. # Sets max password bind failure count to 3
  441. # Reset password retry count (to 0)
  442. config.replace_many(
  443. ('passwordlockout', 'on'),
  444. ('passwordlockoutduration', '30'),
  445. ('passwordresetfailurecount', '30'),
  446. ('passwordmaxfailure', '3'),
  447. ('passwordhistory', 'off'))
  448. user.replace('passwordretrycount', '0')
  449. # Try to bind with invalid credentials(3 times)
  450. for _ in range(3):
  451. with pytest.raises(ldap.INVALID_CREDENTIALS):
  452. _change_password_with_own(topo, user.dn, 'Invalid', 'secreter')
  453. # Try to bind with valid pw, should give lockout error
  454. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  455. _change_password_with_own(topo, user.dn, 'Invalid', 'secreter')
  456. # Reset password using admin login
  457. conn = admin.bind('diradmin')
  458. UserAccount(conn, user.dn).replace('userpassword', 'dby3rs2')
  459. time.sleep(1)
  460. # Try to login as the user to check the unlocking of account. Will also change
  461. # the password back to original
  462. _change_password_with_own(topo, user.dn, 'dby3rs2', 'secreter')
  463. # Change to account lockout forever until reset
  464. # Reset password retry count (to 0)
  465. config.replace('passwordunlock', 'off')
  466. user.replace('passwordretrycount', '0')
  467. # Try to bind with invalid credentials(3 times)
  468. for _ in range(3):
  469. with pytest.raises(ldap.INVALID_CREDENTIALS):
  470. _change_password_with_own(topo, user.dn, 'Invalid', 'secreter')
  471. # Try to bind with valid pw, should give lockout error
  472. with pytest.raises(ldap.CONSTRAINT_VIOLATION):
  473. _change_password_with_own(topo, user.dn, 'Invalid', 'secreter')
  474. # Reset password using admin login
  475. UserAccount(conn, user.dn).replace('userpassword', 'dby3rs2')
  476. time.sleep(1)
  477. # Try to login as the user to check the unlocking of account. Will also change the
  478. # password back to original
  479. _change_password_with_own(topo, user.dn, 'dby3rs2', 'secreter')
  480. if __name__ == "__main__":
  481. CURRENT_FILE = os.path.realpath(__file__)
  482. pytest.main("-s -v %s" % CURRENT_FILE)