3 # Sets password settings (Password complexity, history length,
4 # minimum password length, the minimum and maximum password age) on a
7 # Copyright Jelmer Vernooij 2008
8 # Copyright Matthias Dieter Wallnoefer 2009
9 # Released under the GNU GPL version 3 or later
13 sys
.path
.insert(0, os
.path
.join(os
.path
.dirname(sys
.argv
[0]), "../bin/python"))
15 import samba
.getopt
as options
20 from samba
.auth
import system_session
21 from samba
.samdb
import SamDB
22 from samba
.dcerpc
.samr
import DOMAIN_PASSWORD_COMPLEX
24 parser
= optparse
.OptionParser("pwsettings (show | set <options>)")
25 sambaopts
= options
.SambaOptions(parser
)
26 parser
.add_option_group(sambaopts
)
27 parser
.add_option_group(options
.VersionOptions(parser
))
28 credopts
= options
.CredentialsOptions(parser
)
29 parser
.add_option_group(credopts
)
30 parser
.add_option("-H", help="LDB URL for database or target server", type=str)
31 parser
.add_option("--complexity",
32 help="The password complexity (on | off). Default is 'on'", type=str)
33 parser
.add_option("--history-length",
34 help="The password history length (<integer> | default)", type=str)
35 parser
.add_option("--min-pwd-length",
36 help="The minimum password length (<integer> | default)", type=str)
37 parser
.add_option("--min-pwd-age",
38 help="The minimum password age (<integer in days> | default)", type=str)
39 parser
.add_option("--max-pwd-age",
40 help="The maximum password age (<integer in days> | default)", type=str)
42 opts
, args
= parser
.parse_args()
45 # print a message if quiet is not set
55 lp
= sambaopts
.get_loadparm()
57 creds
= credopts
.get_credentials(lp
)
59 if opts
.H
is not None:
62 url
= lp
.get("sam database")
64 samdb
= SamDB(url
=url
, session_info
=system_session(),
65 credentials
=creds
, lp
=lp
)
67 domain_dn
= SamDB
.domain_dn(samdb
)
68 res
= samdb
.search(domain_dn
, scope
=ldb
.SCOPE_BASE
,
69 attrs
=["pwdProperties", "pwdHistoryLength", "minPwdLength", "minPwdAge",
73 pwd_props
= int(res
[0]["pwdProperties"][0])
74 pwd_hist_len
= int(res
[0]["pwdHistoryLength"][0])
75 min_pwd_len
= int(res
[0]["minPwdLength"][0])
77 min_pwd_age
= int(abs(int(res
[0]["minPwdAge"][0])) / (10e7
* 60 * 60 * 24))
78 max_pwd_age
= int(abs(int(res
[0]["maxPwdAge"][0])) / (10e7
* 60 * 60 * 24))
81 print "ERROR: Password informations missing in your AD domain object!"
82 print "So no settings can be displayed!"
87 print "WARNING: Assuming previous password properties 0 (used for password complexity setting)"
90 print "Password informations for domain '" + domain_dn
+ "'"
92 if pwd_props
& DOMAIN_PASSWORD_COMPLEX
!= 0:
93 print "Password complexity: on"
95 print "Password complexity: off"
96 print "Password history length: " + str(pwd_hist_len
)
97 print "Minimum password length: " + str(min_pwd_len
)
98 print "Minimum password age (days): " + str(min_pwd_age
)
99 print "Maximum password age (days): " + str(max_pwd_age
)
101 elif args
[0] == "set":
102 if opts
.complexity
is not None:
103 if opts
.complexity
== "on":
104 pwd_props
= pwd_props | DOMAIN_PASSWORD_COMPLEX
107 m
.dn
= ldb
.Dn(samdb
, domain_dn
)
108 m
["pwdProperties"] = ldb
.MessageElement([],
109 ldb
.CHANGETYPE_DELETE
, "pwdProperties")
111 m
["pwdProperties"] = ldb
.MessageElement(str(pwd_props
),
112 ldb
.CHANGETYPE_ADD
, "pwdProperties")
114 print "Password complexity activated!"
115 elif opts
.complexity
== "off":
116 pwd_props
= pwd_props
& (~DOMAIN_PASSWORD_COMPLEX
)
119 m
.dn
= ldb
.Dn(samdb
, domain_dn
)
120 m
["pwdProperties"] = ldb
.MessageElement([],
121 ldb
.CHANGETYPE_DELETE
, "pwdProperties")
123 m
["pwdProperties"] = ldb
.MessageElement(str(pwd_props
),
124 ldb
.CHANGETYPE_ADD
, "pwdProperties")
126 print "Password complexity deactivated!"
128 print "ERROR: Wrong argument '" + opts
.complexity
+ "'!"
131 if opts
.history_length
is not None:
132 if opts
.history_length
== "default":
135 pwd_hist_len
= int(opts
.history_length
)
138 m
.dn
= ldb
.Dn(samdb
, domain_dn
)
139 m
["pwdHistoryLength"] = ldb
.MessageElement([],
140 ldb
.CHANGETYPE_DELETE
, "pwdHistoryLength")
142 m
["pwdHistoryLength"] = ldb
.MessageElement(str(pwd_hist_len
),
143 ldb
.CHANGETYPE_ADD
, "pwdHistoryLength")
145 print "Password history length changed!"
147 if opts
.min_pwd_length
is not None:
148 if opts
.min_pwd_length
== "default":
151 min_pwd_len
= int(opts
.min_pwd_length
)
154 m
.dn
= ldb
.Dn(samdb
, domain_dn
)
155 m
["minPwdLength"] = ldb
.MessageElement([],
156 ldb
.CHANGETYPE_DELETE
, "minPwdLength")
158 m
["minPwdLength"] = ldb
.MessageElement(str(min_pwd_len
),
159 ldb
.CHANGETYPE_ADD
, "minPwdLength")
161 print "Minimum password length changed!"
163 if opts
.min_pwd_age
is not None:
164 if opts
.min_pwd_age
== "default":
167 min_pwd_age
= int(opts
.min_pwd_age
)
169 min_pwd_age
= -int(min_pwd_age
* (24 * 60 * 60 * 10e7
))
172 m
.dn
= ldb
.Dn(samdb
, domain_dn
)
173 m
["minPwdAge"] = ldb
.MessageElement([],
174 ldb
.CHANGETYPE_DELETE
, "minPwdAge")
176 m
["minPwdAge"] = ldb
.MessageElement(str(min_pwd_age
),
177 ldb
.CHANGETYPE_ADD
, "minPwdAge")
179 print "Minimum password age changed!"
181 if opts
.max_pwd_age
is not None:
182 if opts
.max_pwd_age
== "default":
185 max_pwd_age
= int(opts
.max_pwd_age
)
187 max_pwd_age
= -int(max_pwd_age
* (24 * 60 * 60 * 10e7
))
190 m
.dn
= ldb
.Dn(samdb
, domain_dn
)
191 m
["maxPwdAge"] = ldb
.MessageElement([],
192 ldb
.CHANGETYPE_DELETE
, "maxPwdAge")
194 m
["maxPwdAge"] = ldb
.MessageElement(str(max_pwd_age
),
195 ldb
.CHANGETYPE_ADD
, "maxPwdAge")
197 print "Maximum password age changed!"
199 print "All changes applied successfully!"
202 print "ERROR: Wrong argument '" + args
[0] + "'!"