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("--quiet", help="Be quiet", action="store_true")
31 parser.add_option("-H", help="LDB URL for database or target server", type=str)
32 parser.add_option("--complexity",
33 help="The password complexity (on | off). Default is 'on'", type=str)
34 parser.add_option("--history-length",
35 help="The password history length (<integer> | default)", type=str)
36 parser.add_option("--min-pwd-length",
37 help="The minimum password length (<integer> | default)", type=str)
38 parser.add_option("--min-pwd-age",
39 help="The minimum password age (<integer in days> | default)", type=str)
40 parser.add_option("--max-pwd-age",
41 help="The maximum password age (<integer in days> | default)", type=str)
43 opts, args = parser.parse_args()
46 # print a message if quiet is not set
56 lp = sambaopts.get_loadparm()
58 creds = credopts.get_credentials(lp)
60 if opts.H is not None:
63 url = lp.get("sam database")
65 samdb = SamDB(url=url, session_info=system_session(),
66 credentials=creds, lp=lp)
68 domain_dn = SamDB.domain_dn(samdb)
69 res = samdb.search(domain_dn, scope=ldb.SCOPE_BASE,
70 attrs=["pwdProperties", "pwdHistoryLength", "minPwdLength", "minPwdAge",
74 pwd_props = int(res[0]["pwdProperties"][0])
75 pwd_hist_len = int(res[0]["pwdHistoryLength"][0])
76 min_pwd_len = int(res[0]["minPwdLength"][0])
78 min_pwd_age = int(abs(int(res[0]["minPwdAge"][0])) / (1e7 * 60 * 60 * 24))
79 max_pwd_age = int(abs(int(res[0]["maxPwdAge"][0])) / (1e7 * 60 * 60 * 24))
82 print "ERROR: Password informations missing in your AD domain object!"
83 print "So no settings can be displayed!"
87 message("WARNING: Assuming previous password properties 0 (used for password complexity setting)")
90 message("Password informations for domain '" + domain_dn + "'")
92 if pwd_props & DOMAIN_PASSWORD_COMPLEX != 0:
93 message("Password complexity: on")
95 message("Password complexity: off")
96 message("Password history length: " + str(pwd_hist_len))
97 message("Minimum password length: " + str(min_pwd_len))
98 message("Minimum password age (days): " + str(min_pwd_age))
99 message("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(str(pwd_props),
109 ldb.FLAG_MOD_REPLACE, "pwdProperties")
111 message("Password complexity activated!")
112 elif opts.complexity == "off":
113 pwd_props = pwd_props & (~DOMAIN_PASSWORD_COMPLEX)
116 m.dn = ldb.Dn(samdb, domain_dn)
117 m["pwdProperties"] = ldb.MessageElement(str(pwd_props),
118 ldb.FLAG_MOD_REPLACE, "pwdProperties")
120 message("Password complexity deactivated!")
122 print "ERROR: Wrong argument '" + opts.complexity + "'!"
125 if opts.history_length is not None:
126 if opts.history_length == "default":
129 pwd_hist_len = int(opts.history_length)
132 m.dn = ldb.Dn(samdb, domain_dn)
133 m["pwdHistoryLength"] = ldb.MessageElement(str(pwd_hist_len),
134 ldb.FLAG_MOD_REPLACE, "pwdHistoryLength")
136 message("Password history length changed!")
138 if opts.min_pwd_length is not None:
139 if opts.min_pwd_length == "default":
142 min_pwd_len = int(opts.min_pwd_length)
145 m.dn = ldb.Dn(samdb, domain_dn)
146 m["minPwdLength"] = ldb.MessageElement(str(min_pwd_len),
147 ldb.FLAG_MOD_REPLACE, "minPwdLength")
149 message("Minimum password length changed!")
151 if opts.min_pwd_age is not None:
152 if opts.min_pwd_age == "default":
155 min_pwd_age = int(opts.min_pwd_age)
157 min_pwd_age = -int(min_pwd_age * (24 * 60 * 60 * 1e7))
160 m.dn = ldb.Dn(samdb, domain_dn)
161 m["minPwdAge"] = ldb.MessageElement(str(min_pwd_age),
162 ldb.FLAG_MOD_REPLACE, "minPwdAge")
164 message("Minimum password age changed!")
166 if opts.max_pwd_age is not None:
167 if opts.max_pwd_age == "default":
170 max_pwd_age = int(opts.max_pwd_age)
172 max_pwd_age = -int(max_pwd_age * (24 * 60 * 60 * 1e7))
175 m.dn = ldb.Dn(samdb, domain_dn)
176 m["maxPwdAge"] = ldb.MessageElement(str(max_pwd_age),
177 ldb.FLAG_MOD_REPLACE, "maxPwdAge")
179 message("Maximum password age changed!")
181 message("All changes applied successfully!")
184 print "ERROR: Wrong argument '" + args[0] + "'!"