2 * Unix SMB/CIFS implementation.
3 * cacusermgr user implementation.
5 * Copyright (C) Chris Nicholls 2005
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 3 of the License, or (at your
10 * option) any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, see <http://www.gnu.org/licenses/>. */
20 #include "cacusermgr.h"
22 void print_user_info(CacUserInfo
*info
) {
24 printf(" User Name : %s\n", info
->username
);
25 printf(" Full Name : %s\n", info
->full_name
);
26 printf(" Home Dir : %s\n", info
->home_dir
);
27 printf(" Home Drive : %s\n", info
->home_drive
);
28 printf(" Profile Path : %s\n", info
->profile_path
);
29 printf(" Logon Script : %s\n", info
->logon_script
);
30 printf(" Description : %s\n", info
->description
);
31 printf(" Workstations : %s\n", info
->workstations
);
32 printf(" Remote Dial : %s\n", info
->dial
);
34 printf(" Logon Time : %s\n", http_timestring(info
->logon_time
));
35 printf(" Logoff Time : %s\n", http_timestring(info
->logoff_time
));
36 printf(" Kickoff Time : %s\n", http_timestring(info
->kickoff_time
));
37 printf(" Pass last set : %s\n", http_timestring(info
->pass_last_set_time
));
38 printf(" Pass can set : %s\n", http_timestring(info
->pass_can_change_time
));
39 printf(" Pass must set : %s\n", http_timestring(info
->pass_must_change_time
));
41 printf(" User RID : 0x%x\n", info
->rid
);
42 printf(" Group RID : 0x%x\n", info
->group_rid
);
43 printf(" User Type : ");
45 if(info
->acb_mask
& ACB_NORMAL
)
46 printf("Normal User\n");
47 else if(info
->acb_mask
& ACB_TEMPDUP
)
48 printf("Temporary Duplicate Account\n");
49 else if(info
->acb_mask
& ACB_DOMTRUST
)
50 printf("Inter-Domain Trust Account\n");
51 else if(info
->acb_mask
& ACB_WSTRUST
)
52 printf("Workstation Trust Account\n");
53 else if(info
->acb_mask
& ACB_SVRTRUST
)
54 printf("Server Trust Account\n");
58 printf(" Disabled : %s\n", (info
->acb_mask
& ACB_DISABLED
) ? "Yes" : "No");
59 printf(" Locked : %s\n", (info
->acb_mask
& ACB_AUTOLOCK
) ? "Yes" : "No");
60 printf(" Pass Expires : %s\n", (info
->acb_mask
& ACB_PWNOEXP
) ? "No" : "Yes");
61 printf(" Pass Required : %s\n", (info
->acb_mask
& ACB_PWNOTREQ
) ? "No" : "Yes");
65 CacUserInfo
*modify_user_info(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*user_hnd
) {
66 CacUserInfo
*info
= NULL
;
69 struct SamGetUserInfo getinfo
;
70 struct SamSetUserInfo setinfo
;
75 getinfo
.in
.user_hnd
= user_hnd
;
77 if(!cac_SamGetUserInfo(hnd
, mem_ctx
, &getinfo
)) {
78 printerr("Could not get user info.", hnd
->status
);
82 info
= getinfo
.out
.info
;
85 printf(" User Name [%s]: ", info
->username
);
88 info
->username
= talloc_strdup(mem_ctx
, tmp
);
90 printf(" Full Name [%s]: ", info
->full_name
);
93 info
->full_name
= talloc_strdup(mem_ctx
, tmp
);
95 printf(" Description [%s]: ", info
->description
);
98 info
->description
= talloc_strdup(mem_ctx
, tmp
);
100 printf(" Home Dir [%s]: ", info
->home_dir
);
103 info
->home_dir
= talloc_strdup(mem_ctx
, tmp
);
105 printf(" Home Drive [%s]: ", info
->home_drive
);
108 info
->home_drive
= talloc_strdup(mem_ctx
, tmp
);
110 printf(" Profile Path [%s]: ", info
->profile_path
);
113 info
->profile_path
= talloc_strdup(mem_ctx
, tmp
);
115 printf(" Logon Script [%s]: ", info
->logon_script
);
118 info
->logon_script
= talloc_strdup(mem_ctx
, tmp
);
120 printf(" Workstations [%s]: ", info
->workstations
);
123 info
->workstations
= talloc_strdup(mem_ctx
, tmp
);
125 printf(" Remote Dial [%s]: ", info
->dial
);
128 info
->dial
= talloc_strdup(mem_ctx
, tmp
);
130 printf(" Disabled [%s] (y/n): ", (info
->acb_mask
& ACB_DISABLED
) ? "Yes" : "No");
132 if(tmp
[0] == 'y' || tmp
[0] == 'Y')
133 info
->acb_mask
|= ACB_DISABLED
;
134 else if(tmp
[0] == 'n' || tmp
[0] == 'N')
135 info
->acb_mask
^= (info
->acb_mask
& ACB_DISABLED
) ? ACB_DISABLED
: 0x0;
137 printf(" Pass Expires [%s] (y/n): ", (info
->acb_mask
& ACB_PWNOEXP
) ? "No" : "Yes");
139 if(tmp
[0] == 'n' || tmp
[0] == 'N')
140 info
->acb_mask
|= ACB_PWNOEXP
;
141 else if(tmp
[0] == 'y' || tmp
[0] == 'Y')
142 info
->acb_mask
^= (info
->acb_mask
& ACB_PWNOEXP
) ? ACB_PWNOEXP
: 0x0;
144 printf(" Pass Required [%s] (y/n): ", (info
->acb_mask
& ACB_PWNOTREQ
) ? "No" : "Yes");
146 if(tmp
[0] == 'n' || tmp
[0] == 'N')
147 info
->acb_mask
|= ACB_PWNOTREQ
;
148 else if(tmp
[0] == 'y' || tmp
[0] == 'Y')
149 info
->acb_mask
^= (info
->acb_mask
& ACB_PWNOTREQ
) ? ACB_PWNOTREQ
: 0x0;
151 setinfo
.in
.user_hnd
= user_hnd
;
152 setinfo
.in
.info
= info
;
154 if(!cac_SamSetUserInfo(hnd
, mem_ctx
, &setinfo
)) {
155 printerr("Could not set user info.", hnd
->status
);
161 void add_user_to_group(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, CacUserInfo
*info
, POLICY_HND
*dom_hnd
) {
166 struct SamOpenGroup og
;
167 struct SamAddGroupMember add
;
172 printf("Group RID or Name:");
174 og
.in
.dom_hnd
= dom_hnd
;
175 og
.in
.access
= MAXIMUM_ALLOWED_ACCESS
;
176 rid_type
= rid_or_name(hnd
, mem_ctx
, dom_hnd
, &og
.in
.rid
, &tmp
);
178 if(!cac_SamOpenGroup(hnd
, mem_ctx
, &og
)) {
179 printerr("Could not open group.", hnd
->status
);
183 add
.in
.group_hnd
= og
.out
.group_hnd
;
184 add
.in
.rid
= info
->rid
;
186 if(!cac_SamAddGroupMember(hnd
, mem_ctx
, &add
)) {
187 printerr("Could not add user to group.", hnd
->status
);
190 cac_SamClose(hnd
, mem_ctx
, og
.out
.group_hnd
);
193 void remove_user_from_group(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, CacUserInfo
*info
, POLICY_HND
*dom_hnd
) {
198 struct SamOpenGroup og
;
199 struct SamRemoveGroupMember del
;
204 printf("Group RID or Name:");
206 og
.in
.dom_hnd
= dom_hnd
;
207 og
.in
.access
= MAXIMUM_ALLOWED_ACCESS
;
208 rid_type
= rid_or_name(hnd
, mem_ctx
, dom_hnd
, &og
.in
.rid
, &tmp
);
210 if(!cac_SamOpenGroup(hnd
, mem_ctx
, &og
)) {
211 printerr("Could not open group.", hnd
->status
);
215 del
.in
.group_hnd
= og
.out
.group_hnd
;
216 del
.in
.rid
= info
->rid
;
218 if(!cac_SamRemoveGroupMember(hnd
, mem_ctx
, &del
)) {
219 printerr("Could not add user to group.", hnd
->status
);
222 cac_SamClose(hnd
, mem_ctx
, og
.out
.group_hnd
);
225 void user_menu(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*dom_hnd
, POLICY_HND
*user_hnd
) {
228 struct SamGetUserInfo getinfo
;
229 struct SamSetPassword setpass
;
230 struct SamGetGroupsForUser groups
;
231 struct SamGetNamesFromRids gnfr
;
233 CacUserInfo
*info
= NULL
;
235 if(!hnd
|| !mem_ctx
|| !user_hnd
) {
236 printf("Must open user.\n");
240 /*get the userinfo and print it out*/
241 ZERO_STRUCT(getinfo
);
242 getinfo
.in
.user_hnd
= user_hnd
;
244 if(!cac_SamGetUserInfo(hnd
, mem_ctx
, &getinfo
)) {
245 printerr("Could not get info.", hnd
->status
);
249 info
= getinfo
.out
.info
;
250 print_user_info(info
);
253 /*now deal with the menu*/
255 while(in
[0] != 'b' && in
[0] != 'B' && in
[0] != 'q' && in
[0] != 'Q') {
257 printf("[s] Set Password\n");
259 if(info
&& (info
->acb_mask
& ACB_DISABLED
))
260 printf("[e] Enable User\n");
262 printf("[d] Disable User\n");
264 printf("[v] View User Info\n");
265 printf("[m] Modify User Info\n");
266 printf("[x] Delete User\n\n");
268 printf("[g] List Group Membership\n");
269 printf("[a] Add User To Group\n");
270 printf("[l] List Domain Groups\n");
271 printf("[r] Remove User From Group\n\n");
273 printf("[b] Back\n\n");
281 case 'g': /*list group membership*/
284 groups
.in
.user_hnd
= user_hnd
;
286 if(!cac_SamGetGroupsForUser(hnd
, mem_ctx
, &groups
)) {
287 printerr("Could not get groups.", hnd
->status
);
292 gnfr
.in
.dom_hnd
= dom_hnd
;
293 gnfr
.in
.rids
= groups
.out
.rids
;
294 gnfr
.in
.num_rids
= groups
.out
.num_groups
;
296 if(!cac_SamGetNamesFromRids(hnd
, mem_ctx
, &gnfr
)) {
297 printerr("Could not map RIDs to names.", hnd
->status
);
301 print_lookup_records(gnfr
.out
.map
, gnfr
.out
.num_names
);
304 case 's': /*reset password*/
306 ZERO_STRUCT(setpass
);
307 setpass
.in
.user_hnd
= user_hnd
;
308 setpass
.in
.password
= get_new_password(mem_ctx
);
310 if(!setpass
.in
.password
) {
311 printf("Out of memory.\n");
315 if(!cac_SamSetPassword(hnd
, mem_ctx
, &setpass
)) {
316 printerr("Could not set password.", hnd
->status
);
319 printf("Reset password.\n");
323 case 'e': /*enable user*/
325 if(info
&& !(info
->acb_mask
& ACB_DISABLED
))
328 if(!cac_SamEnableUser(hnd
, mem_ctx
, user_hnd
)) {
329 printerr("Could not enable user.", hnd
->status
);
332 printf("Enabled User.\n");
333 /*toggle the disabled ACB bit in our local copy of the info*/
334 info
->acb_mask
^= ACB_DISABLED
;
338 case 'd': /*disable user*/
340 if(info
&& (info
->acb_mask
& ACB_DISABLED
))
343 if(!cac_SamDisableUser(hnd
, mem_ctx
, user_hnd
)) {
344 printerr("Could not disable user.", hnd
->status
);
347 printf("Disabled User.\n");
348 /*toggle the disabled ACB bit in our local copy of the info*/
349 info
->acb_mask
^= ACB_DISABLED
;
353 case 'v': /*view user info*/
355 ZERO_STRUCT(getinfo
);
356 getinfo
.in
.user_hnd
= user_hnd
;
358 if(!cac_SamGetUserInfo(hnd
, mem_ctx
, &getinfo
)) {
359 printerr("Could not get info.", hnd
->status
);
363 info
= getinfo
.out
.info
;
364 print_user_info(info
);
369 case 'm': /*modify user info*/
371 info
= modify_user_info(hnd
, mem_ctx
, user_hnd
);
374 printf("Updated user info.\n");
377 case 'l': /*list domain groups*/
379 list_groups(hnd
, mem_ctx
, dom_hnd
);
382 case 'a': /*add user to group*/
384 add_user_to_group(hnd
, mem_ctx
, info
, dom_hnd
);
387 case 'r': /*remove user from group*/
389 remove_user_from_group(hnd
, mem_ctx
, info
, dom_hnd
);
392 case 'x': /*delete user*/
394 if(!cac_SamDeleteUser(hnd
, mem_ctx
, user_hnd
))
395 printerr("Could not delete user.", hnd
->status
);
397 /*we want to go back to the main menu*/
409 printf("Invalid command.\n");
413 /*close the user before returning*/
414 cac_SamClose(hnd
, mem_ctx
, user_hnd
);