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] + "'!"