2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Jean François Micouleau 1998-2001.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern pstring global_myname
;
25 extern fstring global_myworkgroup
;
28 * Next two lines needed for SunOS and don't
29 * hurt anything else...
34 /*********************************************************
35 Print command usage on stderr and die.
36 **********************************************************/
37 static void usage(void)
40 printf("smbgroupedit options\n");
42 printf("You need to be root to use this tool!\n");
45 printf(" -a group create new group\n");
46 printf(" -n group NT group name\n");
47 printf(" -p privilege only local\n");
48 printf(" -d description group description\n");
49 printf(" -v list groups\n");
50 printf(" -l long list (include details)\n");
51 printf(" -s short list (default)\n");
52 printf(" -c SID change group\n");
53 printf(" -u unix group\n");
54 printf(" -d description group description\n");
55 printf(" -x group delete this group\n");
57 printf(" -t[b|d|l] type: builtin, domain, local \n");
61 /*********************************************************
62 Figure out if the input was an NT group or a SID string.
64 **********************************************************/
65 static BOOL
get_sid_from_input(DOM_SID
*sid
, char *input
)
69 if (StrnCaseCmp( input
, "S-", 2)) {
70 /* Perhaps its the NT group name? */
71 if (!get_group_map_from_ntname(input
, &map
, MAPPING_WITHOUT_PRIV
)) {
72 printf("NT Group %s doesn't exist in mapping DB\n", input
);
78 if (!string_to_sid(sid
, input
)) {
79 printf("converting sid %s from a string failed!\n", input
);
86 /*********************************************************
88 **********************************************************/
89 static int addgroup(char *group
, enum SID_NAME_USE sid_type
, char *ntgroup
, char *ntcomment
, char *privilege
)
91 PRIVILEGE_SET se_priv
;
95 fstring name
, comment
;
99 printf("unix group %s doesn't exist!\n", group
);
103 local_gid_to_sid(&sid
, gid
);
105 sid_to_string(string_sid
, &sid
);
108 fstrcpy(name
, group
);
110 fstrcpy(name
, ntgroup
);
113 fstrcpy(comment
, "Local Unix group");
115 fstrcpy(comment
, ntcomment
);
117 init_privilege(&se_priv
);
119 convert_priv_from_text(&se_priv
, privilege
);
121 if(!add_initial_entry(gid
, string_sid
, sid_type
, name
, comment
, se_priv
, PR_ACCESS_FROM_NETWORK
)) {
122 printf("adding entry for group %s failed!\n", group
);
123 free_privilege(&se_priv
);
127 free_privilege(&se_priv
);
131 /*********************************************************
133 **********************************************************/
134 static int changegroup(char *sid_string
, char *group
, enum SID_NAME_USE sid_type
, char *ntgroup
, char *groupdesc
, char *privilege
)
140 if (!get_sid_from_input(&sid
, sid_string
)) {
144 /* Get the current mapping from the database */
145 if(!get_group_map_from_sid(sid
, &map
, MAPPING_WITH_PRIV
)) {
146 printf("This SID does not exist in the database\n");
150 /* If a new Unix group is specified, check and change */
152 gid
=nametogid(group
);
154 printf("The UNIX group does not exist\n");
161 * Allow changing of group type only between domain and local
162 * We disallow changing Builtin groups !!! (SID problem)
164 if (sid_type
==SID_NAME_ALIAS
165 || sid_type
==SID_NAME_DOM_GRP
166 || sid_type
==SID_NAME_UNKNOWN
) {
167 if (map
.sid_name_use
==SID_NAME_ALIAS
168 || map
.sid_name_use
==SID_NAME_DOM_GRP
169 || map
.sid_name_use
==SID_NAME_UNKNOWN
) {
170 map
.sid_name_use
=sid_type
;
172 printf("cannot change group type to builtin\n");
175 printf("cannot change group type from builtin\n");
179 fstrcpy(map
.nt_name
, ntgroup
);
181 /* Change comment if new one */
183 fstrcpy(map
.comment
, groupdesc
);
185 /* Change the privilege if new one */
187 convert_priv_from_text(&map
.priv_set
, privilege
);
189 if (!add_mapping_entry(&map
, TDB_REPLACE
)) {
190 printf("Count not update group database\n");
191 free_privilege(&map
.priv_set
);
195 free_privilege(&map
.priv_set
);
199 /*********************************************************
201 **********************************************************/
202 static int deletegroup(char *group
)
206 if (!get_sid_from_input(&sid
, group
)) {
210 if(!group_map_remove(sid
)) {
211 printf("removing group %s from the mapping db failed!\n", group
);
218 /*********************************************************
220 **********************************************************/
221 static int listgroup(enum SID_NAME_USE sid_type
, BOOL long_list
)
230 printf("NT group (SID) -> Unix group\n");
232 if (!enum_group_mapping(sid_type
, &map
, &entries
, ENUM_ALL_MAPPED
, MAPPING_WITH_PRIV
))
235 for (i
=0; i
<entries
; i
++) {
236 decode_sid_name_use(group_type
, (map
[i
]).sid_name_use
);
237 sid_to_string(string_sid
, &map
[i
].sid
);
238 convert_priv_to_text(&(map
[i
].priv_set
), priv_text
);
239 free_privilege(&(map
[i
].priv_set
));
242 printf("%s (%s) -> %s\n", map
[i
].nt_name
, string_sid
, gidtoname(map
[i
].gid
));
244 printf("%s\n", map
[i
].nt_name
);
245 printf("\tSID : %s\n", string_sid
);
246 printf("\tUnix group: %s\n", gidtoname(map
[i
].gid
));
247 printf("\tGroup type: %s\n", group_type
);
248 printf("\tComment : %s\n", map
[i
].comment
);
249 printf("\tPrivilege : %s\n\n", priv_text
);
256 /*********************************************************
258 **********************************************************/
259 int main (int argc
, char **argv
)
262 BOOL add_group
= False
;
263 BOOL view_group
= False
;
264 BOOL change_group
= False
;
265 BOOL delete_group
= False
;
266 BOOL nt_group
= False
;
268 BOOL group_type
= False
;
269 BOOL long_list
= False
;
273 char *ntgroup
= NULL
;
274 char *privilege
= NULL
;
276 char *group_desc
= NULL
;
278 enum SID_NAME_USE sid_type
;
280 setup_logging("groupedit", True
);
287 if (!lp_load(dyn_CONFIGFILE
,True
,False
,False
)) {
288 fprintf(stderr
, "Can't load %s - run testparm to debug it\n",
293 if (!*global_myname
) {
295 pstrcpy( global_myname
, myhostname() );
296 p
= strchr_m(global_myname
, '.' );
301 strupper(global_myname
);
303 fstrcpy(global_myworkgroup
, lp_workgroup());
305 if(!initialize_password_db(True
)) {
306 fprintf(stderr
, "Can't setup password database vectors.\n");
310 if(get_global_sam_sid()==False
) {
311 fprintf(stderr
, "Can not read machine SID\n");
315 while ((ch
= getopt(argc
, argv
, "a:c:d:ln:p:st:u:vx:")) != EOF
) {
362 if (((add_group
?1:0) + (view_group
?1:0) + (change_group
?1:0) + (delete_group
?1:0)) > 1) {
363 fprintf (stderr
, "Incompatible options on command line!\n");
368 /* no option on command line -> list groups */
369 if (((add_group
?1:0) + (view_group
?1:0) + (change_group
?1:0) + (delete_group
?1:0)) == 0)
373 if (group_type
==False
)
374 sid_type
=SID_NAME_UNKNOWN
;
379 sid_type
=SID_NAME_ALIAS
;
383 sid_type
=SID_NAME_DOM_GRP
;
387 sid_type
=SID_NAME_WKN_GRP
;
390 sid_type
=SID_NAME_UNKNOWN
;
396 return addgroup(group
, sid_type
, ntgroup
, group_desc
, privilege
);
399 return listgroup(sid_type
, long_list
);
402 return deletegroup(group
);
405 return changegroup(sid
, group
, sid_type
, ntgroup
, group_desc
, privilege
);