5 # Copyright Jelmer Vernooij 2010 <jelmer@samba.org>
6 # Copyright Theresa Halloran 2011 <theresahalloran@gmail.com>
7 # Copyright Giampaolo Lauria 2011 <lauria2@yahoo.com>
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 3 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 import samba
.getopt
as options
25 from getpass
import getpass
26 from samba
.auth
import system_session
27 from samba
.samdb
import SamDB
28 from samba
import gensec
29 from samba
.net
import Net
31 from samba
.netcmd
import (
40 class cmd_user_add(Command
):
41 """Creates a new user"""
43 synopsis
= "%prog user add <username> [<password>] [options]"
46 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
47 metavar
="URL", dest
="H"),
48 Option("--must-change-at-next-login",
49 help="Force password to be changed on next login",
51 Option("--use-username-as-cn",
52 help="Force use of username as user's CN",
55 help="Alternative location (without domainDN counterpart) to default CN=Users in which new user object will be created",
57 Option("--surname", help="User's surname", type=str),
58 Option("--given-name", help="User's given name", type=str),
59 Option("--initials", help="User's initials", type=str),
60 Option("--profile-path", help="User's profile path", type=str),
61 Option("--script-path", help="User's logon script path", type=str),
62 Option("--home-drive", help="User's home drive letter", type=str),
63 Option("--home-directory", help="User's home directory path", type=str),
64 Option("--job-title", help="User's job title", type=str),
65 Option("--department", help="User's department", type=str),
66 Option("--company", help="User's company", type=str),
67 Option("--description", help="User's description", type=str),
68 Option("--mail-address", help="User's email address", type=str),
69 Option("--internet-address", help="User's home page", type=str),
70 Option("--telephone-number", help="User's phone number", type=str),
71 Option("--physical-delivery-office", help="User's office location", type=str),
74 takes_args
= ["username", "password?"]
76 def run(self
, username
, password
=None, credopts
=None, sambaopts
=None,
77 versionopts
=None, H
=None, must_change_at_next_login
=None,
78 use_username_as_cn
=None, userou
=None, surname
=None, given_name
=None, initials
=None,
79 profile_path
=None, script_path
=None, home_drive
=None, home_directory
=None,
80 job_title
=None, department
=None, company
=None, description
=None,
81 mail_address
=None, internet_address
=None, telephone_number
=None, physical_delivery_office
=None):
84 if password
is not None and password
is not '':
86 password
= getpass("New Password: ")
88 lp
= sambaopts
.get_loadparm()
89 creds
= credopts
.get_credentials(lp
)
92 samdb
= SamDB(url
=H
, session_info
=system_session(),
93 credentials
=creds
, lp
=lp
)
94 samdb
.newuser(username
, password
,
95 force_password_change_at_next_login_req
=must_change_at_next_login
,
96 useusernameascn
=use_username_as_cn
, userou
=userou
, surname
=surname
, givenname
=given_name
, initials
=initials
,
97 profilepath
=profile_path
, homedrive
=home_drive
, scriptpath
=script_path
, homedirectory
=home_directory
,
98 jobtitle
=job_title
, department
=department
, company
=company
, description
=description
,
99 mailaddress
=mail_address
, internetaddress
=internet_address
,
100 telephonenumber
=telephone_number
, physicaldeliveryoffice
=physical_delivery_office
)
102 raise CommandError("Failed to add user '%s': " % username
, e
)
104 self
.outf
.write("User '%s' created successfully\n" % username
)
107 class cmd_user_delete(Command
):
110 synopsis
= "%prog user delete <username> [options]"
113 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
114 metavar
="URL", dest
="H"),
117 takes_args
= ["username"]
119 def run(self
, username
, credopts
=None, sambaopts
=None, versionopts
=None, H
=None):
121 lp
= sambaopts
.get_loadparm()
122 creds
= credopts
.get_credentials(lp
, fallback_machine
=True)
125 samdb
= SamDB(url
=H
, session_info
=system_session(),
126 credentials
=creds
, lp
=lp
)
127 samdb
.deleteuser(username
)
129 raise CommandError('Failed to remove user "%s"' % username
, e
)
130 self
.outf
.write("Deleted user %s\n" % username
)
133 class cmd_user_enable(Command
):
136 synopsis
= "%prog user enable (<username>|--filter <filter>) [options]"
139 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
140 metavar
="URL", dest
="H"),
141 Option("--filter", help="LDAP Filter to set password on", type=str),
144 takes_args
= ["username?"]
146 def run(self
, username
=None, sambaopts
=None, credopts
=None,
147 versionopts
=None, filter=None, H
=None):
148 if username
is None and filter is None:
149 raise CommandError("Either the username or '--filter' must be specified!")
152 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb
.binary_encode(username
))
154 lp
= sambaopts
.get_loadparm()
155 creds
= credopts
.get_credentials(lp
, fallback_machine
=True)
157 samdb
= SamDB(url
=H
, session_info
=system_session(),
158 credentials
=creds
, lp
=lp
)
160 samdb
.enable_account(filter)
161 except Exception, msg
:
162 raise CommandError("Failed to enable user '%s': %s" % (username
or filter, msg
))
163 self
.outf
.write("Enabled user '%s'\n" % (username
or filter))
166 class cmd_user_setexpiry(Command
):
167 """Sets the expiration of a user account"""
169 synopsis
= "%prog user setexpiry (<username>|--filter <filter>) [options]"
172 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
173 metavar
="URL", dest
="H"),
174 Option("--filter", help="LDAP Filter to set password on", type=str),
175 Option("--days", help="Days to expiry", type=int, default
=0),
176 Option("--noexpiry", help="Password does never expire", action
="store_true", default
=False),
179 takes_args
= ["username?"]
181 def run(self
, username
=None, sambaopts
=None, credopts
=None,
182 versionopts
=None, H
=None, filter=None, days
=None, noexpiry
=None):
183 if username
is None and filter is None:
184 raise CommandError("Either the username or '--filter' must be specified!")
187 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb
.binary_encode(username
))
189 lp
= sambaopts
.get_loadparm()
190 creds
= credopts
.get_credentials(lp
)
192 samdb
= SamDB(url
=H
, session_info
=system_session(),
193 credentials
=creds
, lp
=lp
)
196 samdb
.setexpiry(filter, days
*24*3600, no_expiry_req
=noexpiry
)
197 except Exception, msg
:
198 # FIXME: Catch more specific exception
199 raise CommandError("Failed to set expiry for user '%s': %s" % (
200 username
or filter, msg
))
201 self
.outf
.write("Set expiry for user '%s' to %u days\n" % (
202 username
or filter, days
))
205 class cmd_user_password(Command
):
206 """Change password for a user account (the one provided in authentication)"""
208 synopsis
= "%prog user password [options]"
211 Option("--newpassword", help="New password", type=str),
214 def run(self
, credopts
=None, sambaopts
=None, versionopts
=None,
217 lp
= sambaopts
.get_loadparm()
218 creds
= credopts
.get_credentials(lp
)
220 # get old password now, to get the password prompts in the right order
221 old_password
= creds
.get_password()
223 net
= Net(creds
, lp
, server
=credopts
.ipaddress
)
225 password
= newpassword
227 if password
is not None and password
is not '':
229 password
= getpass("New Password: ")
232 net
.change_password(password
)
233 except Exception, msg
:
234 # FIXME: catch more specific exception
235 raise CommandError("Failed to change password : %s" % msg
)
236 self
.outf
.write("Changed password OK\n")
239 class cmd_user_setpassword(Command
):
240 """(Re)sets the password of a user account"""
242 synopsis
= "%prog user setpassword (<username>|--filter <filter>) [options]"
245 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
246 metavar
="URL", dest
="H"),
247 Option("--filter", help="LDAP Filter to set password on", type=str),
248 Option("--newpassword", help="Set password", type=str),
249 Option("--must-change-at-next-login",
250 help="Force password to be changed on next login",
251 action
="store_true"),
254 takes_args
= ["username?"]
256 def run(self
, username
=None, filter=None, credopts
=None, sambaopts
=None,
257 versionopts
=None, H
=None, newpassword
=None,
258 must_change_at_next_login
=None):
259 if filter is None and username
is None:
260 raise CommandError("Either the username or '--filter' must be specified!")
262 password
= newpassword
264 if password
is not None and password
is not '':
266 password
= getpass("New Password: ")
269 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb
.binary_encode(username
))
271 lp
= sambaopts
.get_loadparm()
272 creds
= credopts
.get_credentials(lp
)
274 creds
.set_gensec_features(creds
.get_gensec_features() | gensec
.FEATURE_SEAL
)
276 samdb
= SamDB(url
=H
, session_info
=system_session(),
277 credentials
=creds
, lp
=lp
)
280 samdb
.setpassword(filter, password
,
281 force_change_at_next_login
=must_change_at_next_login
,
283 except Exception, msg
:
284 # FIXME: catch more specific exception
285 raise CommandError("Failed to set password for user '%s': %s" % (username
or filter, msg
))
286 self
.outf
.write("Changed password OK\n")
290 class cmd_user(SuperCommand
):
291 """User management"""
294 subcommands
["add"] = cmd_user_add()
295 subcommands
["delete"] = cmd_user_delete()
296 subcommands
["enable"] = cmd_user_enable()
297 subcommands
["setexpiry"] = cmd_user_setexpiry()
298 subcommands
["password"] = cmd_user_password()
299 subcommands
["setpassword"] = cmd_user_setpassword()