netcmd: user: readpasswords: move getpassword command to readpasswords
[Samba.git] / python / samba / netcmd / user / add_unix_attrs.py
blob693b541217cd8ac6d296581f10a56da16cc68b5a
1 # user management
3 # user add_unix_attrs command
5 # Copyright Jelmer Vernooij 2010 <jelmer@samba.org>
6 # Copyright Theresa Halloran 2011 <theresahalloran@gmail.com>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 import samba.getopt as options
23 from samba import ldb
24 from samba.auth import system_session
25 from samba.netcmd import Command, CommandError, Option
26 from samba.samdb import SamDB
29 class cmd_user_add_unix_attrs(Command):
30 """Add RFC2307 attributes to a user.
32 This command adds Unix attributes to a user account in the Active
33 Directory domain.
35 The username specified on the command is the sAMaccountName.
37 You must supply a unique uidNumber.
39 Unix (RFC2307) attributes will be added to the user account.
41 If you supply a gidNumber with '--gid-number', this will be used for the
42 users Unix 'gidNumber' attribute.
44 If '--gid-number' is not supplied, the users Unix gidNumber will be set to the
45 one found in 'Domain Users', this means Domain Users must have a gidNumber
46 attribute.
48 if '--unix-home' is not supplied, the users Unix home directory will be
49 set to /home/DOMAIN/username
51 if '--login-shell' is not supplied, the users Unix login shell will be
52 set to '/bin/sh'
54 if ---gecos' is not supplied, the users Unix gecos field will be set to the
55 users 'CN'
57 Add 'idmap_ldb:use rfc2307 = Yes' to the smb.conf on DCs, to use these
58 attributes for UID/GID mapping.
60 The command may be run from the root userid or another authorised userid.
61 The -H or --URL= option can be used to execute the command against a
62 remote server.
64 Example1:
65 samba-tool user addunixattrs User1 10001
67 Example1 shows how to add RFC2307 attributes to a domain enabled user
68 account, Domain Users will be set as the users gidNumber.
70 The users Unix ID will be set to '10001', provided this ID isn't already
71 in use.
73 Example2:
74 samba-tool user addunixattrs User2 10002 --gid-number=10001 \
75 --unix-home=/home/User2
77 Example2 shows how to add RFC2307 attributes to a domain enabled user
78 account.
80 The users Unix ID will be set to '10002', provided this ID isn't already
81 in use.
83 The users gidNumber attribute will be set to '10001'
85 The users Unix home directory will be set to '/home/user2'
87 Example3:
88 samba-tool user addunixattrs User3 10003 --gid-number=10001 \
89 --login-shell=/bin/false --gecos='User3 test'
91 Example3 shows how to add RFC2307 attributes to a domain enabled user
92 account.
94 The users Unix ID will be set to '10003', provided this ID isn't already
95 in use.
97 The users gidNumber attribute will be set to '10001'
99 The users Unix login shell will be set to '/bin/false'
101 The users gecos field will be set to 'User3 test'
103 Example4:
104 samba-tool user addunixattrs User4 10004 --gid-number=10001 \
105 --unix-home=/home/User4 --login-shell=/bin/bash --gecos='User4 test'
107 Example4 shows how to add RFC2307 attributes to a domain enabled user
108 account.
110 The users Unix ID will be set to '10004', provided this ID isn't already
111 in use.
113 The users gidNumber attribute will be set to '10001'
115 The users Unix home directory will be set to '/home/User4'
117 The users Unix login shell will be set to '/bin/bash'
119 The users gecos field will be set to 'User4 test'
123 synopsis = "%prog <username> <uid-number> [options]"
125 takes_options = [
126 Option("-H", "--URL", help="LDB URL for database or target server",
127 type=str, metavar="URL", dest="H"),
128 Option("--gid-number", help="User's Unix/RFC2307 GID", type=str),
129 Option("--unix-home", help="User's Unix/RFC2307 home directory",
130 type=str),
131 Option("--login-shell", help="User's Unix/RFC2307 login shell",
132 type=str),
133 Option("--gecos", help="User's Unix/RFC2307 GECOS field", type=str),
134 Option("--uid", help="User's Unix/RFC2307 username", type=str),
137 takes_args = ["username", "uid-number"]
139 takes_optiongroups = {
140 "sambaopts": options.SambaOptions,
141 "credopts": options.CredentialsOptions,
142 "versionopts": options.VersionOptions,
145 def run(self, username, uid_number, credopts=None, sambaopts=None,
146 versionopts=None, H=None, gid_number=None, unix_home=None,
147 login_shell=None, gecos=None, uid=None):
149 lp = sambaopts.get_loadparm()
150 creds = credopts.get_credentials(lp)
152 samdb = SamDB(url=H, session_info=system_session(),
153 credentials=creds, lp=lp)
155 domaindn = samdb.domain_dn()
157 # Check that uidNumber supplied isn't already in use
158 filter = ("(&(objectClass=person)(uidNumber={}))"
159 .format(uid_number))
160 res = samdb.search(domaindn,
161 scope=ldb.SCOPE_SUBTREE,
162 expression=filter)
163 if (len(res) != 0):
164 raise CommandError("uidNumber {} is already being used."
165 .format(uid_number))
167 # Check user exists and doesn't have a uidNumber
168 filter = "(samaccountname={})".format(ldb.binary_encode(username))
169 res = samdb.search(domaindn,
170 scope=ldb.SCOPE_SUBTREE,
171 expression=filter)
172 if (len(res) == 0):
173 raise CommandError("Unable to find user '{}'".format(username))
175 user_dn = res[0].dn
177 if "uidNumber" in res[0]:
178 raise CommandError("User {} is already a Unix user."
179 .format(username))
181 if gecos is None:
182 gecos = res[0]["cn"][0]
184 if uid is None:
185 uid = res[0]["cn"][0]
187 if gid_number is None:
188 search_filter = ("(samaccountname={})"
189 .format(ldb.binary_encode('Domain Users')))
190 try:
191 res = samdb.search(domaindn,
192 scope=ldb.SCOPE_SUBTREE,
193 expression=search_filter)
194 for msg in res:
195 gid_number=msg.get('gidNumber')
196 except IndexError:
197 raise CommandError('Domain Users does not have a'
198 ' gidNumber attribute')
200 if login_shell is None:
201 login_shell = "/bin/sh"
203 if unix_home is None:
204 # obtain nETBIOS Domain Name
205 unix_domain = samdb.domain_netbios_name()
206 if unix_domain is None:
207 raise CommandError('Unable to find Unix domain')
209 tmpl = lp.get('template homedir')
210 unix_home = tmpl.replace('%D', unix_domain).replace('%U', username)
212 if not lp.get("idmap_ldb:use rfc2307"):
213 self.outf.write("You are setting a Unix/RFC2307 UID & GID. "
214 "You may want to set 'idmap_ldb:use rfc2307 = Yes'"
215 " in smb.conf to use the attributes for "
216 "XID/SID-mapping.\n")
218 user_mod = """
219 dn: {0}
220 changetype: modify
221 add: uidNumber
222 uidNumber: {1}
223 add: gidnumber
224 gidNumber: {2}
225 add: gecos
226 gecos: {3}
227 add: uid
228 uid: {4}
229 add: loginshell
230 loginShell: {5}
231 add: unixHomeDirectory
232 unixHomeDirectory: {6}
233 """.format(user_dn, uid_number, gid_number, gecos, uid, login_shell, unix_home)
235 samdb.transaction_start()
236 try:
237 samdb.modify_ldif(user_mod)
238 except ldb.LdbError as e:
239 raise CommandError("Failed to modify user '{0}': {1}"
240 .format(username, e))
241 else:
242 samdb.transaction_commit()
243 self.outf.write("Modified User '{}' successfully\n"
244 .format(username))