samba-tool: changed samba-tool user delete to use samdb instead of Net()
[gd/samba-autobuild/.git] / source4 / scripting / python / samba / netcmd / user.py
1 #!/usr/bin/env python
2 #
3 # user management
4 #
5 # Copyright Jelmer Vernooij 2010 <jelmer@samba.org>
6 # Copyright Theresa Halloran 2011 <theresahalloran@gmail.com>
7 # Copyright Giampaolo Lauria 2011 <lauria2@yahoo.com>
8 #
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.
13 #
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.
18 #
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/>.
21 #
22
23 import samba.getopt as options
24 import sys, ldb
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
30
31 from samba.netcmd import (
32     Command,
33     CommandError,
34     SuperCommand,
35     Option,
36     )
37
38
39
40 class cmd_user_add(Command):
41     """Creates a new user"""
42
43     synopsis = "%prog user add <username> [<password>] [options]"
44
45     takes_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",
50                 action="store_true"),
51         Option("--use-username-as-cn",
52                 help="Force use of username as user's CN",
53                 action="store_true"),
54         Option("--userou",
55                 help="Alternative location (without domainDN counterpart) to default CN=Users in which new user object will be created",
56                 type=str),
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),
72     ]
73
74     takes_args = ["username", "password?"]
75
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):
82
83         while 1:
84             if password is not None and password is not '':
85                 break
86             password = getpass("New Password: ")
87
88         lp = sambaopts.get_loadparm()
89         creds = credopts.get_credentials(lp)
90
91         try:
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)
101         except Exception, e:
102             raise CommandError("Failed to add user '%s': " % username, e)
103
104         print("User '%s' created successfully" % username)
105
106
107
108 class cmd_user_delete(Command):
109     """Delete a user"""
110
111     synopsis = "%prog user delete <username>"
112
113     takes_options = [
114         Option("-H", "--URL", help="LDB URL for database or target server", type=str,
115                metavar="URL", dest="H"),
116     ]
117
118     takes_args = ["username"]
119
120     def run(self, username, credopts=None, sambaopts=None, versionopts=None, H=None):
121
122         lp = sambaopts.get_loadparm()
123         creds = credopts.get_credentials(lp, fallback_machine=True)
124
125         try:
126             samdb = SamDB(url=H, session_info=system_session(),
127                           credentials=creds, lp=lp)
128             samdb.deleteuser(username)
129         except Exception, e:
130             raise CommandError('Failed to remove user "%s"' % username, e)
131         print("Deleted user %s" % username)
132
133
134 class cmd_user_enable(Command):
135     """Enables a user"""
136
137     synopsis = "%prog user enable (<username>|--filter <filter>) [options]"
138
139     takes_options = [
140         Option("-H", "--URL", help="LDB URL for database or target server", type=str,
141                metavar="URL", dest="H"),
142         Option("--filter", help="LDAP Filter to set password on", type=str),
143         ]
144
145     takes_args = ["username?"]
146
147     def run(self, username=None, sambaopts=None, credopts=None,
148             versionopts=None, filter=None, H=None):
149         if username is None and filter is None:
150             raise CommandError("Either the username or '--filter' must be specified!")
151
152         if filter is None:
153             filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
154
155         lp = sambaopts.get_loadparm()
156         creds = credopts.get_credentials(lp, fallback_machine=True)
157
158         samdb = SamDB(url=H, session_info=system_session(),
159             credentials=creds, lp=lp)
160         try:
161             samdb.enable_account(filter)
162         except Exception, msg:
163             raise CommandError("Failed to enable user '%s': %s" % (username or filter, msg))
164         print("Enabled user '%s'" % (username or filter))
165
166
167
168 class cmd_user_setexpiry(Command):
169     """Sets the expiration of a user account"""
170
171     synopsis = "%prog user setexpiry (<username>|--filter <filter>) [options]"
172
173     takes_options = [
174         Option("-H", "--URL", help="LDB URL for database or target server", type=str,
175                metavar="URL", dest="H"),
176         Option("--filter", help="LDAP Filter to set password on", type=str),
177         Option("--days", help="Days to expiry", type=int, default=0),
178         Option("--noexpiry", help="Password does never expire", action="store_true", default=False),
179     ]
180
181     takes_args = ["username?"]
182
183     def run(self, username=None, sambaopts=None, credopts=None,
184             versionopts=None, H=None, filter=None, days=None, noexpiry=None):
185         if username is None and filter is None:
186             raise CommandError("Either the username or '--filter' must be specified!")
187
188         if filter is None:
189             filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
190
191         lp = sambaopts.get_loadparm()
192         creds = credopts.get_credentials(lp)
193
194         samdb = SamDB(url=H, session_info=system_session(),
195             credentials=creds, lp=lp)
196
197         try:
198             samdb.setexpiry(filter, days*24*3600, no_expiry_req=noexpiry)
199         except Exception, msg:
200             raise CommandError("Failed to set expiry for user '%s': %s" % (username or filter, msg))
201         print("Set expiry for user '%s' to %u days" % (username or filter, days))
202
203
204
205 class cmd_user_password(Command):
206     """Change password for a user account (the one provided in authentication)"""
207
208     synopsis = "%prog user password [options]"
209
210     takes_options = [
211         Option("--newpassword", help="New password", type=str),
212         ]
213
214     def run(self, credopts=None, sambaopts=None, versionopts=None,
215                 newpassword=None):
216
217         lp = sambaopts.get_loadparm()
218         creds = credopts.get_credentials(lp)
219
220         # get old password now, to get the password prompts in the right order
221         old_password = creds.get_password()
222
223         net = Net(creds, lp, server=credopts.ipaddress)
224
225         password = newpassword
226         while 1:
227             if password is not None and password is not '':
228                 break
229             password = getpass("New Password: ")
230
231         try:
232             net.change_password(password)
233         except Exception, msg:
234             raise CommandError("Failed to change password : %s" % msg)
235         print "Changed password OK"
236
237
238
239 class cmd_user_setpassword(Command):
240     """(Re)sets the password of a user account"""
241
242     synopsis = "%prog user setpassword (<username>|--filter <filter>) [options]"
243
244     takes_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"),
252         ]
253
254     takes_args = ["username?"]
255
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!")
261
262         password = newpassword
263         while 1:
264             if password is not None and password is not '':
265                 break
266             password = getpass("New Password: ")
267
268         if filter is None:
269             filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
270
271         lp = sambaopts.get_loadparm()
272         creds = credopts.get_credentials(lp)
273
274         creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
275
276         samdb = SamDB(url=H, session_info=system_session(),
277                       credentials=creds, lp=lp)
278
279         try:
280             samdb.setpassword(filter, password,
281                               force_change_at_next_login=must_change_at_next_login,
282                               username=username)
283         except Exception, msg:
284             raise CommandError("Failed to set password for user '%s': %s" % (username or filter, msg))
285         print "Changed password OK"
286
287
288
289 class cmd_user(SuperCommand):
290     """User management [server connection needed]"""
291
292     subcommands = {}
293     subcommands["add"] = cmd_user_add()
294     subcommands["delete"] = cmd_user_delete()
295     subcommands["enable"] = cmd_user_enable()
296     subcommands["setexpiry"] = cmd_user_setexpiry()
297     subcommands["password"] = cmd_user_password()
298     subcommands["setpassword"] = cmd_user_setpassword()