Line data Source code
1 : /*
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.
6 : * Copyright (C) Gerald Carter 2003,
7 : * Copyright (C) Volker Lendecke 2004
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 :
24 : #include "includes.h"
25 : #include "system/passwd.h"
26 : #include "utils/net.h"
27 : #include "../libcli/security/security.h"
28 : #include "passdb.h"
29 : #include "lib/util/string_wrappers.h"
30 :
31 : /*********************************************************
32 : Figure out if the input was an NT group or a SID string.
33 : Return the SID.
34 : **********************************************************/
35 161 : static bool get_sid_from_input(struct dom_sid *sid, char *input)
36 : {
37 0 : GROUP_MAP *map;
38 :
39 161 : map = talloc_zero(NULL, GROUP_MAP);
40 161 : if (!map) {
41 0 : return false;
42 : }
43 :
44 161 : if (strncasecmp_m( input, "S-", 2)) {
45 : /* Perhaps its the NT group name? */
46 159 : if (!pdb_getgrnam(map, input)) {
47 147 : printf(_("NT Group %s doesn't exist in mapping DB\n"),
48 : input);
49 147 : TALLOC_FREE(map);
50 147 : return false;
51 : } else {
52 12 : *sid = map->sid;
53 : }
54 : } else {
55 2 : if (!string_to_sid(sid, input)) {
56 0 : printf(_("converting sid %s from a string failed!\n"),
57 : input);
58 0 : TALLOC_FREE(map);
59 0 : return false;
60 : }
61 : }
62 14 : TALLOC_FREE(map);
63 14 : return true;
64 : }
65 :
66 : /*********************************************************
67 : Dump a GROUP_MAP entry to stdout (long or short listing)
68 : **********************************************************/
69 :
70 0 : static void print_map_entry (const GROUP_MAP *map, bool long_list)
71 : {
72 0 : struct dom_sid_buf buf;
73 :
74 0 : if (!long_list)
75 0 : d_printf("%s (%s) -> %s\n", map->nt_name,
76 : dom_sid_str_buf(&map->sid, &buf),
77 0 : gidtoname(map->gid));
78 : else {
79 0 : d_printf("%s\n", map->nt_name);
80 0 : d_printf(_("\tSID : %s\n"),
81 : dom_sid_str_buf(&map->sid, &buf));
82 0 : d_printf(_("\tUnix gid : %u\n"), (unsigned int)map->gid);
83 0 : d_printf(_("\tUnix group: %s\n"), gidtoname(map->gid));
84 0 : d_printf(_("\tGroup type: %s\n"),
85 0 : sid_type_lookup(map->sid_name_use));
86 0 : d_printf(_("\tComment : %s\n"), map->comment);
87 : }
88 :
89 0 : }
90 : /*********************************************************
91 : List the groups.
92 : **********************************************************/
93 0 : static int net_groupmap_list(struct net_context *c, int argc, const char **argv)
94 : {
95 0 : size_t entries;
96 0 : bool long_list = false;
97 0 : size_t i;
98 0 : fstring ntgroup = "";
99 0 : fstring sid_string = "";
100 0 : const char list_usage_str[] = N_("net groupmap list [verbose] "
101 : "[ntgroup=NT group] [sid=SID]\n"
102 : " verbose\tPrint verbose list\n"
103 : " ntgroup\tNT group to list\n"
104 : " sid\tSID of group to list");
105 :
106 0 : if (c->display_usage) {
107 0 : d_printf("%s\n%s\n", _("Usage: "), list_usage_str);
108 0 : return 0;
109 : }
110 :
111 0 : if (c->opt_verbose || c->opt_long_list_entries)
112 0 : long_list = true;
113 :
114 : /* get the options */
115 0 : for ( i=0; i<argc; i++ ) {
116 0 : if ( !strcasecmp_m(argv[i], "verbose")) {
117 0 : long_list = true;
118 : }
119 0 : else if ( !strncasecmp_m(argv[i], "ntgroup", strlen("ntgroup")) ) {
120 0 : fstrcpy( ntgroup, get_string_param( argv[i] ) );
121 0 : if ( !ntgroup[0] ) {
122 0 : d_fprintf(stderr, _("must supply a name\n"));
123 0 : return -1;
124 : }
125 : }
126 0 : else if ( !strncasecmp_m(argv[i], "sid", strlen("sid")) ) {
127 0 : fstrcpy( sid_string, get_string_param( argv[i] ) );
128 0 : if ( !sid_string[0] ) {
129 0 : d_fprintf(stderr, _("must supply a SID\n"));
130 0 : return -1;
131 : }
132 : }
133 : else {
134 0 : d_fprintf(stderr, _("Bad option: %s\n"), argv[i]);
135 0 : d_printf("%s\n%s\n", _("Usage:"), list_usage_str);
136 0 : return -1;
137 : }
138 : }
139 :
140 : /* list a single group is given a name */
141 0 : if ( ntgroup[0] || sid_string[0] ) {
142 0 : struct dom_sid sid;
143 0 : GROUP_MAP *map;
144 :
145 0 : if ( sid_string[0] )
146 0 : strlcpy(ntgroup, sid_string, sizeof(ntgroup));
147 :
148 0 : if (!get_sid_from_input(&sid, ntgroup)) {
149 0 : return -1;
150 : }
151 :
152 0 : map = talloc_zero(NULL, GROUP_MAP);
153 0 : if (!map) {
154 0 : return -1;
155 : }
156 :
157 : /* Get the current mapping from the database */
158 0 : if(!pdb_getgrsid(map, sid)) {
159 0 : d_fprintf(stderr,
160 0 : _("Failure to find local group SID in the "
161 : "database\n"));
162 0 : TALLOC_FREE(map);
163 0 : return -1;
164 : }
165 :
166 0 : print_map_entry(map, long_list );
167 0 : TALLOC_FREE(map);
168 : }
169 : else {
170 0 : GROUP_MAP **maps = NULL;
171 0 : bool ok = false;
172 : /* enumerate all group mappings */
173 0 : ok = pdb_enum_group_mapping(NULL, SID_NAME_UNKNOWN,
174 : &maps, &entries,
175 : ENUM_ALL_MAPPED);
176 0 : if (!ok) {
177 0 : return -1;
178 : }
179 :
180 0 : for (i=0; i<entries; i++) {
181 0 : print_map_entry(maps[i], long_list);
182 : }
183 :
184 0 : TALLOC_FREE(maps);
185 : }
186 :
187 0 : return 0;
188 : }
189 :
190 : /*********************************************************
191 : Add a new group mapping entry
192 : **********************************************************/
193 :
194 161 : static int net_groupmap_add(struct net_context *c, int argc, const char **argv)
195 : {
196 0 : struct dom_sid sid;
197 161 : fstring ntgroup = "";
198 161 : fstring unixgrp = "";
199 161 : fstring string_sid = "";
200 161 : fstring type = "";
201 161 : fstring ntcomment = "";
202 161 : enum lsa_SidType sid_type = SID_NAME_DOM_GRP;
203 161 : uint32_t rid = 0;
204 0 : gid_t gid;
205 0 : int i;
206 0 : GROUP_MAP *map;
207 :
208 0 : const char *name_type;
209 161 : const char add_usage_str[] = N_("net groupmap add "
210 : "{rid=<int>|sid=<string>}"
211 : " unixgroup=<string> "
212 : "[type=<domain|local|builtin>] "
213 : "[ntgroup=<string>] "
214 : "[comment=<string>]");
215 :
216 161 : name_type = "domain group";
217 :
218 161 : if (c->display_usage) {
219 0 : d_printf("%s\n%s\n", _("Usage:\n"), add_usage_str);
220 0 : return 0;
221 : }
222 :
223 : /* get the options */
224 644 : for ( i=0; i<argc; i++ ) {
225 483 : if ( !strncasecmp_m(argv[i], "rid", strlen("rid")) ) {
226 106 : rid = get_int_param(argv[i]);
227 106 : if ( rid < DOMAIN_RID_ADMINS ) {
228 0 : d_fprintf(stderr,
229 0 : _("RID must be greater than %d\n"),
230 : (uint32_t)DOMAIN_RID_ADMINS-1);
231 0 : return -1;
232 : }
233 : }
234 377 : else if ( !strncasecmp_m(argv[i], "unixgroup", strlen("unixgroup")) ) {
235 161 : fstrcpy( unixgrp, get_string_param( argv[i] ) );
236 161 : if ( !unixgrp[0] ) {
237 0 : d_fprintf(stderr,_( "must supply a name\n"));
238 0 : return -1;
239 : }
240 : }
241 216 : else if ( !strncasecmp_m(argv[i], "ntgroup", strlen("ntgroup")) ) {
242 0 : fstrcpy( ntgroup, get_string_param( argv[i] ) );
243 0 : if ( !ntgroup[0] ) {
244 0 : d_fprintf(stderr, _("must supply a name\n"));
245 0 : return -1;
246 : }
247 : }
248 216 : else if ( !strncasecmp_m(argv[i], "sid", strlen("sid")) ) {
249 55 : fstrcpy( string_sid, get_string_param( argv[i] ) );
250 55 : if ( !string_sid[0] ) {
251 0 : d_fprintf(stderr, _("must supply a SID\n"));
252 0 : return -1;
253 : }
254 : }
255 161 : else if ( !strncasecmp_m(argv[i], "comment", strlen("comment")) ) {
256 0 : fstrcpy( ntcomment, get_string_param( argv[i] ) );
257 0 : if ( !ntcomment[0] ) {
258 0 : d_fprintf(stderr,
259 0 : _("must supply a comment string\n"));
260 0 : return -1;
261 : }
262 : }
263 161 : else if ( !strncasecmp_m(argv[i], "type", strlen("type")) ) {
264 161 : fstrcpy( type, get_string_param( argv[i] ) );
265 161 : switch ( type[0] ) {
266 55 : case 'b':
267 : case 'B':
268 55 : sid_type = SID_NAME_WKN_GRP;
269 55 : name_type = "wellknown group";
270 55 : break;
271 106 : case 'd':
272 : case 'D':
273 106 : sid_type = SID_NAME_DOM_GRP;
274 106 : name_type = "domain group";
275 106 : break;
276 0 : case 'l':
277 : case 'L':
278 0 : sid_type = SID_NAME_ALIAS;
279 0 : name_type = "alias (local) group";
280 0 : break;
281 0 : default:
282 0 : d_fprintf(stderr,
283 0 : _("unknown group type %s\n"),
284 : type);
285 0 : return -1;
286 : }
287 : }
288 : else {
289 0 : d_fprintf(stderr, _("Bad option: %s\n"), argv[i]);
290 0 : return -1;
291 : }
292 : }
293 :
294 161 : if ( !unixgrp[0] ) {
295 0 : d_printf("%s\n%s\n", _("Usage:\n"), add_usage_str);
296 0 : return -1;
297 : }
298 :
299 161 : if ( (gid = nametogid(unixgrp)) == (gid_t)-1 ) {
300 0 : d_fprintf(stderr, _("Can't lookup UNIX group %s\n"), unixgrp);
301 0 : return -1;
302 : }
303 :
304 161 : map = talloc_zero(NULL, GROUP_MAP);
305 161 : if (!map) {
306 0 : return -1;
307 : }
308 : /* Default is domain group. */
309 161 : map->sid_name_use = SID_NAME_DOM_GRP;
310 161 : if (pdb_getgrgid(map, gid)) {
311 0 : struct dom_sid_buf buf;
312 0 : d_printf(_("Unix group %s already mapped to SID %s\n"),
313 0 : unixgrp, dom_sid_str_buf(&map->sid, &buf));
314 0 : TALLOC_FREE(map);
315 0 : return -1;
316 : }
317 161 : TALLOC_FREE(map);
318 :
319 161 : if ( (rid == 0) && (string_sid[0] == '\0') ) {
320 0 : d_printf(_("No rid or sid specified, choosing a RID\n"));
321 0 : if (pdb_capabilities() & PDB_CAP_STORE_RIDS) {
322 0 : if (!pdb_new_rid(&rid)) {
323 0 : d_printf(_("Could not get new RID\n"));
324 : }
325 : } else {
326 0 : rid = algorithmic_pdb_gid_to_group_rid(gid);
327 : }
328 0 : d_printf(_("Got RID %d\n"), rid);
329 : }
330 :
331 : /* append the rid to our own domain/machine SID if we don't have a full SID */
332 161 : if ( !string_sid[0] ) {
333 106 : sid_compose(&sid, get_global_sam_sid(), rid);
334 106 : sid_to_fstring(string_sid, &sid);
335 : }
336 :
337 161 : if (!ntcomment[0]) {
338 161 : switch (sid_type) {
339 55 : case SID_NAME_WKN_GRP:
340 55 : fstrcpy(ntcomment, "Wellknown Unix group");
341 55 : break;
342 106 : case SID_NAME_DOM_GRP:
343 106 : fstrcpy(ntcomment, "Domain Unix group");
344 106 : break;
345 0 : case SID_NAME_ALIAS:
346 0 : fstrcpy(ntcomment, "Local Unix group");
347 0 : break;
348 0 : default:
349 0 : fstrcpy(ntcomment, "Unix group");
350 0 : break;
351 : }
352 : }
353 :
354 161 : if (!ntgroup[0] )
355 161 : strlcpy(ntgroup, unixgrp, sizeof(ntgroup));
356 :
357 161 : if (!NT_STATUS_IS_OK(add_initial_entry(gid, string_sid, sid_type, ntgroup, ntcomment))) {
358 0 : d_fprintf(stderr, _("adding entry for group %s failed!\n"), ntgroup);
359 0 : return -1;
360 : }
361 :
362 161 : d_printf(_("Successfully added group %s to the mapping db as a %s\n"),
363 : ntgroup, name_type);
364 161 : return 0;
365 : }
366 :
367 0 : static int net_groupmap_modify(struct net_context *c, int argc, const char **argv)
368 : {
369 0 : struct dom_sid sid;
370 0 : GROUP_MAP *map = NULL;
371 0 : fstring ntcomment = "";
372 0 : fstring type = "";
373 0 : fstring ntgroup = "";
374 0 : fstring unixgrp = "";
375 0 : fstring sid_string = "";
376 0 : enum lsa_SidType sid_type = SID_NAME_UNKNOWN;
377 0 : int i;
378 0 : gid_t gid;
379 0 : const char modify_usage_str[] = N_("net groupmap modify "
380 : "{ntgroup=<string>|sid=<SID>} "
381 : "[comment=<string>] "
382 : "[unixgroup=<string>] "
383 : "[type=<domain|local>]");
384 :
385 0 : if (c->display_usage) {
386 0 : d_printf("%s\n%s\n", _("Usage:\n"), modify_usage_str);
387 0 : return 0;
388 : }
389 :
390 : /* get the options */
391 0 : for ( i=0; i<argc; i++ ) {
392 0 : if ( !strncasecmp_m(argv[i], "ntgroup", strlen("ntgroup")) ) {
393 0 : fstrcpy( ntgroup, get_string_param( argv[i] ) );
394 0 : if ( !ntgroup[0] ) {
395 0 : d_fprintf(stderr, _("must supply a name\n"));
396 0 : return -1;
397 : }
398 : }
399 0 : else if ( !strncasecmp_m(argv[i], "sid", strlen("sid")) ) {
400 0 : fstrcpy( sid_string, get_string_param( argv[i] ) );
401 0 : if ( !sid_string[0] ) {
402 0 : d_fprintf(stderr, _("must supply a name\n"));
403 0 : return -1;
404 : }
405 : }
406 0 : else if ( !strncasecmp_m(argv[i], "comment", strlen("comment")) ) {
407 0 : fstrcpy( ntcomment, get_string_param( argv[i] ) );
408 0 : if ( !ntcomment[0] ) {
409 0 : d_fprintf(stderr,
410 0 : _("must supply a comment string\n"));
411 0 : return -1;
412 : }
413 : }
414 0 : else if ( !strncasecmp_m(argv[i], "unixgroup", strlen("unixgroup")) ) {
415 0 : fstrcpy( unixgrp, get_string_param( argv[i] ) );
416 0 : if ( !unixgrp[0] ) {
417 0 : d_fprintf(stderr,
418 0 : _("must supply a group name\n"));
419 0 : return -1;
420 : }
421 : }
422 0 : else if ( !strncasecmp_m(argv[i], "type", strlen("type")) ) {
423 0 : fstrcpy( type, get_string_param( argv[i] ) );
424 0 : switch ( type[0] ) {
425 0 : case 'd':
426 : case 'D':
427 0 : sid_type = SID_NAME_DOM_GRP;
428 0 : break;
429 0 : case 'l':
430 : case 'L':
431 0 : sid_type = SID_NAME_ALIAS;
432 0 : break;
433 : }
434 : }
435 : else {
436 0 : d_fprintf(stderr, _("Bad option: %s\n"), argv[i]);
437 0 : return -1;
438 : }
439 : }
440 :
441 0 : if ( !ntgroup[0] && !sid_string[0] ) {
442 0 : d_printf("%s\n%s\n", _("Usage:\n"), modify_usage_str);
443 0 : return -1;
444 : }
445 :
446 : /* give preference to the SID; if both the ntgroup name and SID
447 : are defined, use the SID and assume that the group name could be a
448 : new name */
449 :
450 0 : if ( sid_string[0] ) {
451 0 : if (!get_sid_from_input(&sid, sid_string)) {
452 0 : return -1;
453 : }
454 : }
455 : else {
456 0 : if (!get_sid_from_input(&sid, ntgroup)) {
457 0 : return -1;
458 : }
459 : }
460 :
461 0 : map = talloc_zero(NULL, GROUP_MAP);
462 0 : if (!map) {
463 0 : return -1;
464 : }
465 :
466 : /* Get the current mapping from the database */
467 0 : if(!pdb_getgrsid(map, sid)) {
468 0 : d_fprintf(stderr,
469 0 : _("Failed to find local group SID in the database\n"));
470 0 : TALLOC_FREE(map);
471 0 : return -1;
472 : }
473 :
474 : /*
475 : * Allow changing of group type only between domain and local
476 : * We disallow changing Builtin groups !!! (SID problem)
477 : */
478 0 : if (sid_type == SID_NAME_UNKNOWN) {
479 0 : d_fprintf(stderr, _("Can't map to an unknown group type.\n"));
480 0 : TALLOC_FREE(map);
481 0 : return -1;
482 : }
483 :
484 0 : if (map->sid_name_use == SID_NAME_WKN_GRP) {
485 0 : d_fprintf(stderr,
486 0 : _("You can only change between domain and local "
487 : "groups.\n"));
488 0 : TALLOC_FREE(map);
489 0 : return -1;
490 : }
491 :
492 0 : map->sid_name_use = sid_type;
493 :
494 : /* Change comment if new one */
495 0 : if (ntcomment[0]) {
496 0 : map->comment = talloc_strdup(map, ntcomment);
497 0 : if (!map->comment) {
498 0 : d_fprintf(stderr, _("Out of memory!\n"));
499 0 : return -1;
500 : }
501 : }
502 :
503 0 : if (ntgroup[0]) {
504 0 : map->nt_name = talloc_strdup(map, ntgroup);
505 0 : if (!map->nt_name) {
506 0 : d_fprintf(stderr, _("Out of memory!\n"));
507 0 : return -1;
508 : }
509 : }
510 :
511 0 : if ( unixgrp[0] ) {
512 0 : gid = nametogid( unixgrp );
513 0 : if ( gid == -1 ) {
514 0 : d_fprintf(stderr, _("Unable to lookup UNIX group %s. "
515 : "Make sure the group exists.\n"),
516 : unixgrp);
517 0 : TALLOC_FREE(map);
518 0 : return -1;
519 : }
520 :
521 0 : map->gid = gid;
522 : }
523 :
524 0 : if (!NT_STATUS_IS_OK(pdb_update_group_mapping_entry(map))) {
525 0 : d_fprintf(stderr, _("Could not update group database\n"));
526 0 : TALLOC_FREE(map);
527 0 : return -1;
528 : }
529 :
530 0 : d_printf(_("Updated mapping entry for %s\n"), map->nt_name);
531 :
532 0 : TALLOC_FREE(map);
533 0 : return 0;
534 : }
535 :
536 161 : static int net_groupmap_delete(struct net_context *c, int argc, const char **argv)
537 : {
538 0 : struct dom_sid sid;
539 161 : fstring ntgroup = "";
540 161 : fstring sid_string = "";
541 0 : int i;
542 161 : const char delete_usage_str[] = N_("net groupmap delete "
543 : "{ntgroup=<string>|sid=<SID>}");
544 :
545 161 : if (c->display_usage) {
546 0 : d_printf("%s\n%s\n", _("Usage:\n"), delete_usage_str);
547 0 : return 0;
548 : }
549 :
550 : /* get the options */
551 322 : for ( i=0; i<argc; i++ ) {
552 161 : if ( !strncasecmp_m(argv[i], "ntgroup", strlen("ntgroup")) ) {
553 159 : fstrcpy( ntgroup, get_string_param( argv[i] ) );
554 159 : if ( !ntgroup[0] ) {
555 0 : d_fprintf(stderr, _("must supply a name\n"));
556 0 : return -1;
557 : }
558 : }
559 2 : else if ( !strncasecmp_m(argv[i], "sid", strlen("sid")) ) {
560 2 : fstrcpy( sid_string, get_string_param( argv[i] ) );
561 2 : if ( !sid_string[0] ) {
562 0 : d_fprintf(stderr, _("must supply a SID\n"));
563 0 : return -1;
564 : }
565 : }
566 : else {
567 0 : d_fprintf(stderr, _("Bad option: %s\n"), argv[i]);
568 0 : return -1;
569 : }
570 : }
571 :
572 161 : if ( !ntgroup[0] && !sid_string[0]) {
573 0 : d_printf("%s\n%s\n", _("Usage:\n"), delete_usage_str);
574 0 : return -1;
575 : }
576 :
577 : /* give preference to the SID if we have that */
578 :
579 161 : if ( sid_string[0] )
580 2 : strlcpy(ntgroup, sid_string, sizeof(ntgroup));
581 :
582 161 : if ( !get_sid_from_input(&sid, ntgroup) ) {
583 147 : d_fprintf(stderr, _("Unable to resolve group %s to a SID\n"),
584 : ntgroup);
585 147 : return -1;
586 : }
587 :
588 14 : if ( !NT_STATUS_IS_OK(pdb_delete_group_mapping_entry(sid)) ) {
589 0 : d_fprintf(stderr,
590 0 : _("Failed to remove group %s from the mapping db!\n"),
591 : ntgroup);
592 0 : return -1;
593 : }
594 :
595 14 : d_printf(_("Successfully removed %s from the mapping db\n"), ntgroup);
596 :
597 14 : return 0;
598 : }
599 :
600 0 : static int net_groupmap_set(struct net_context *c, int argc, const char **argv)
601 : {
602 0 : const char *ntgroup = NULL;
603 0 : struct group *grp = NULL;
604 0 : GROUP_MAP *map;
605 0 : bool have_map = false;
606 :
607 0 : if ((argc < 1) || (argc > 2) || c->display_usage) {
608 0 : d_printf("%s\n%s",
609 : _("Usage:"),
610 : _(" net groupmap set \"NT Group\" "
611 : "[\"unix group\"] [-C \"comment\"] [-L] [-D]\n"));
612 0 : return -1;
613 : }
614 :
615 0 : if ( c->opt_localgroup && c->opt_domaingroup ) {
616 0 : d_printf(_("Can only specify -L or -D, not both\n"));
617 0 : return -1;
618 : }
619 :
620 0 : ntgroup = argv[0];
621 :
622 0 : if (argc == 2) {
623 0 : grp = getgrnam(argv[1]);
624 :
625 0 : if (grp == NULL) {
626 0 : d_fprintf(stderr, _("Could not find unix group %s\n"),
627 0 : argv[1]);
628 0 : return -1;
629 : }
630 : }
631 :
632 0 : map = talloc_zero(NULL, GROUP_MAP);
633 0 : if (!map) {
634 0 : d_printf(_("Out of memory!\n"));
635 0 : return -1;
636 : }
637 :
638 0 : have_map = pdb_getgrnam(map, ntgroup);
639 :
640 0 : if (!have_map) {
641 0 : struct dom_sid sid;
642 0 : have_map = ( (strncmp(ntgroup, "S-", 2) == 0) &&
643 0 : string_to_sid(&sid, ntgroup) &&
644 0 : pdb_getgrsid(map, sid) );
645 : }
646 :
647 0 : if (!have_map) {
648 :
649 : /* Ok, add it */
650 :
651 0 : if (grp == NULL) {
652 0 : d_fprintf(stderr,
653 0 : _("Could not find group mapping for %s\n"),
654 : ntgroup);
655 0 : TALLOC_FREE(map);
656 0 : return -1;
657 : }
658 :
659 0 : map->gid = grp->gr_gid;
660 :
661 0 : if (c->opt_rid == 0) {
662 0 : if ( pdb_capabilities() & PDB_CAP_STORE_RIDS ) {
663 0 : if ( !pdb_new_rid((uint32_t *)&c->opt_rid) ) {
664 0 : d_fprintf( stderr,
665 0 : _("Could not allocate new RID\n"));
666 0 : TALLOC_FREE(map);
667 0 : return -1;
668 : }
669 : } else {
670 0 : c->opt_rid = algorithmic_pdb_gid_to_group_rid(map->gid);
671 : }
672 : }
673 :
674 0 : sid_compose(&map->sid, get_global_sam_sid(), c->opt_rid);
675 :
676 0 : map->sid_name_use = SID_NAME_DOM_GRP;
677 0 : map->nt_name = talloc_strdup(map, ntgroup);
678 0 : map->comment = talloc_strdup(map, "");
679 0 : if (!map->nt_name || !map->comment) {
680 0 : d_printf(_("Out of memory!\n"));
681 0 : TALLOC_FREE(map);
682 0 : return -1;
683 : }
684 :
685 0 : if (!NT_STATUS_IS_OK(pdb_add_group_mapping_entry(map))) {
686 0 : d_fprintf(stderr,
687 0 : _("Could not add mapping entry for %s\n"),
688 : ntgroup);
689 0 : TALLOC_FREE(map);
690 0 : return -1;
691 : }
692 : }
693 :
694 : /* Now we have a mapping entry, update that stuff */
695 :
696 0 : if ( c->opt_localgroup || c->opt_domaingroup ) {
697 0 : if (map->sid_name_use == SID_NAME_WKN_GRP) {
698 0 : d_fprintf(stderr,
699 0 : _("Can't change type of the BUILTIN "
700 : "group %s\n"),
701 : map->nt_name);
702 0 : TALLOC_FREE(map);
703 0 : return -1;
704 : }
705 : }
706 :
707 0 : if (c->opt_localgroup)
708 0 : map->sid_name_use = SID_NAME_ALIAS;
709 :
710 0 : if (c->opt_domaingroup)
711 0 : map->sid_name_use = SID_NAME_DOM_GRP;
712 :
713 : /* The case (opt_domaingroup && opt_localgroup) was tested for above */
714 :
715 0 : if ((c->opt_comment != NULL) && (strlen(c->opt_comment) > 0)) {
716 0 : map->comment = talloc_strdup(map, c->opt_comment);
717 0 : if (!map->comment) {
718 0 : d_printf(_("Out of memory!\n"));
719 0 : TALLOC_FREE(map);
720 0 : return -1;
721 : }
722 : }
723 :
724 0 : if ((c->opt_newntname != NULL) && (strlen(c->opt_newntname) > 0)) {
725 0 : map->nt_name = talloc_strdup(map, c->opt_newntname);
726 0 : if (!map->nt_name) {
727 0 : d_printf(_("Out of memory!\n"));
728 0 : TALLOC_FREE(map);
729 0 : return -1;
730 : }
731 : }
732 :
733 0 : if (grp != NULL)
734 0 : map->gid = grp->gr_gid;
735 :
736 0 : if (!NT_STATUS_IS_OK(pdb_update_group_mapping_entry(map))) {
737 0 : d_fprintf(stderr, _("Could not update group mapping for %s\n"),
738 : ntgroup);
739 0 : TALLOC_FREE(map);
740 0 : return -1;
741 : }
742 :
743 0 : TALLOC_FREE(map);
744 0 : return 0;
745 : }
746 :
747 0 : static int net_groupmap_cleanup(struct net_context *c, int argc, const char **argv)
748 : {
749 0 : GROUP_MAP **maps = NULL;
750 0 : size_t i, entries;
751 :
752 0 : if (c->display_usage) {
753 0 : d_printf( "%s\n"
754 : "net groupmap cleanup\n"
755 : " %s\n",
756 : _("Usage:"),
757 : _("Delete all group mappings"));
758 0 : return 0;
759 : }
760 :
761 0 : if (!pdb_enum_group_mapping(NULL, SID_NAME_UNKNOWN, &maps, &entries,
762 : ENUM_ALL_MAPPED)) {
763 0 : d_fprintf(stderr, _("Could not list group mappings\n"));
764 0 : return -1;
765 : }
766 :
767 0 : for (i=0; i<entries; i++) {
768 :
769 0 : if (maps[i]->gid == -1)
770 0 : printf(_("Group %s is not mapped\n"),
771 0 : maps[i]->nt_name);
772 :
773 0 : if (!sid_check_is_in_our_sam(&maps[i]->sid) &&
774 0 : !sid_check_is_in_builtin(&maps[i]->sid))
775 : {
776 0 : struct dom_sid_buf buf;
777 0 : printf(_("Deleting mapping for NT Group %s, sid %s\n"),
778 0 : maps[i]->nt_name,
779 0 : dom_sid_str_buf(&maps[i]->sid, &buf));
780 0 : pdb_delete_group_mapping_entry(maps[i]->sid);
781 : }
782 : }
783 :
784 0 : TALLOC_FREE(maps);
785 0 : return 0;
786 : }
787 :
788 10 : static int net_groupmap_addmem(struct net_context *c, int argc, const char **argv)
789 : {
790 0 : struct dom_sid alias, member;
791 :
792 10 : if ( (argc != 2) ||
793 10 : c->display_usage ||
794 10 : !string_to_sid(&alias, argv[0]) ||
795 10 : !string_to_sid(&member, argv[1]) ) {
796 0 : d_printf("%s\n%s",
797 : _("Usage:"),
798 : _("net groupmap addmem alias-sid member-sid\n"));
799 0 : return -1;
800 : }
801 :
802 10 : if (!NT_STATUS_IS_OK(pdb_add_aliasmem(&alias, &member))) {
803 0 : d_fprintf(stderr, _("Could not add sid %s to alias %s\n"),
804 0 : argv[1], argv[0]);
805 0 : return -1;
806 : }
807 :
808 10 : return 0;
809 : }
810 :
811 10 : static int net_groupmap_delmem(struct net_context *c, int argc, const char **argv)
812 : {
813 0 : struct dom_sid alias, member;
814 :
815 10 : if ( (argc != 2) ||
816 10 : c->display_usage ||
817 10 : !string_to_sid(&alias, argv[0]) ||
818 10 : !string_to_sid(&member, argv[1]) ) {
819 0 : d_printf("%s\n%s",
820 : _("Usage:"),
821 : _("net groupmap delmem alias-sid member-sid\n"));
822 0 : return -1;
823 : }
824 :
825 10 : if (!NT_STATUS_IS_OK(pdb_del_aliasmem(&alias, &member))) {
826 0 : d_fprintf(stderr, _("Could not delete sid %s from alias %s\n"),
827 0 : argv[1], argv[0]);
828 0 : return -1;
829 : }
830 :
831 10 : return 0;
832 : }
833 :
834 6 : static int net_groupmap_listmem(struct net_context *c, int argc, const char **argv)
835 : {
836 0 : struct dom_sid alias;
837 0 : struct dom_sid *members;
838 0 : size_t i, num;
839 :
840 6 : if ( (argc != 1) ||
841 6 : c->display_usage ||
842 6 : !string_to_sid(&alias, argv[0]) ) {
843 0 : d_printf("%s\n%s",
844 : _("Usage:"),
845 : _("net groupmap listmem alias-sid\n"));
846 0 : return -1;
847 : }
848 :
849 6 : members = NULL;
850 6 : num = 0;
851 :
852 6 : if (!NT_STATUS_IS_OK(pdb_enum_aliasmem(&alias, talloc_tos(),
853 : &members, &num))) {
854 0 : d_fprintf(stderr, _("Could not list members for sid %s\n"),
855 : argv[0]);
856 0 : return -1;
857 : }
858 :
859 22 : for (i = 0; i < num; i++) {
860 0 : struct dom_sid_buf buf;
861 16 : printf("%s\n", dom_sid_str_buf(&(members[i]), &buf));
862 : }
863 :
864 6 : TALLOC_FREE(members);
865 :
866 6 : return 0;
867 : }
868 :
869 0 : static bool print_alias_memberships(TALLOC_CTX *mem_ctx,
870 : const struct dom_sid *domain_sid,
871 : const struct dom_sid *member)
872 : {
873 0 : uint32_t *alias_rids;
874 0 : size_t i, num_alias_rids;
875 0 : struct dom_sid_buf buf;
876 :
877 0 : alias_rids = NULL;
878 0 : num_alias_rids = 0;
879 :
880 0 : if (!NT_STATUS_IS_OK(pdb_enum_alias_memberships(
881 : mem_ctx, domain_sid, member, 1,
882 : &alias_rids, &num_alias_rids))) {
883 0 : d_fprintf(stderr, _("Could not list memberships for sid %s\n"),
884 : dom_sid_str_buf(member, &buf));
885 0 : return false;
886 : }
887 :
888 0 : for (i = 0; i < num_alias_rids; i++) {
889 0 : struct dom_sid alias;
890 0 : sid_compose(&alias, domain_sid, alias_rids[i]);
891 0 : printf("%s\n", dom_sid_str_buf(&alias, &buf));
892 : }
893 :
894 0 : return true;
895 : }
896 :
897 0 : static int net_groupmap_memberships(struct net_context *c, int argc, const char **argv)
898 : {
899 0 : TALLOC_CTX *mem_ctx;
900 0 : struct dom_sid *domain_sid, member;
901 :
902 0 : if ( (argc != 1) ||
903 0 : c->display_usage ||
904 0 : !string_to_sid(&member, argv[0]) ) {
905 0 : d_printf("%s\n%s",
906 : _("Usage:"),
907 : _("net groupmap memberships sid\n"));
908 0 : return -1;
909 : }
910 :
911 0 : mem_ctx = talloc_init("net_groupmap_memberships");
912 0 : if (mem_ctx == NULL) {
913 0 : d_fprintf(stderr, _("talloc_init failed\n"));
914 0 : return -1;
915 : }
916 :
917 0 : domain_sid = get_global_sam_sid();
918 0 : if (domain_sid == NULL) {
919 0 : d_fprintf(stderr, _("Could not get domain sid\n"));
920 0 : return -1;
921 : }
922 :
923 0 : if (!print_alias_memberships(mem_ctx, domain_sid, &member) ||
924 0 : !print_alias_memberships(mem_ctx, &global_sid_Builtin, &member))
925 0 : return -1;
926 :
927 0 : talloc_destroy(mem_ctx);
928 :
929 0 : return 0;
930 : }
931 :
932 : /***********************************************************
933 : migrated functionality from smbgroupedit
934 : **********************************************************/
935 348 : int net_groupmap(struct net_context *c, int argc, const char **argv)
936 : {
937 348 : struct functable func[] = {
938 : {
939 : "add",
940 : net_groupmap_add,
941 : NET_TRANSPORT_LOCAL,
942 : N_("Create a new group mapping"),
943 : N_("net groupmap add\n"
944 : " Create a new group mapping")
945 : },
946 : {
947 : "modify",
948 : net_groupmap_modify,
949 : NET_TRANSPORT_LOCAL,
950 : N_("Update a group mapping"),
951 : N_("net groupmap modify\n"
952 : " Modify an existing group mapping")
953 : },
954 : {
955 : "delete",
956 : net_groupmap_delete,
957 : NET_TRANSPORT_LOCAL,
958 : N_("Remove a group mapping"),
959 : N_("net groupmap delete\n"
960 : " Remove a group mapping")
961 : },
962 : {
963 : "set",
964 : net_groupmap_set,
965 : NET_TRANSPORT_LOCAL,
966 : N_("Set group mapping"),
967 : N_("net groupmap set\n"
968 : " Set a group mapping")
969 : },
970 : {
971 : "cleanup",
972 : net_groupmap_cleanup,
973 : NET_TRANSPORT_LOCAL,
974 : N_("Remove foreign group mapping entries"),
975 : N_("net groupmap cleanup\n"
976 : " Remove foreign group mapping entries")
977 : },
978 : {
979 : "addmem",
980 : net_groupmap_addmem,
981 : NET_TRANSPORT_LOCAL,
982 : N_("Add a foreign alias member"),
983 : N_("net groupmap addmem\n"
984 : " Add a foreign alias member")
985 : },
986 : {
987 : "delmem",
988 : net_groupmap_delmem,
989 : NET_TRANSPORT_LOCAL,
990 : N_("Delete foreign alias member"),
991 : N_("net groupmap delmem\n"
992 : " Delete foreign alias member")
993 : },
994 : {
995 : "listmem",
996 : net_groupmap_listmem,
997 : NET_TRANSPORT_LOCAL,
998 : N_("List foreign group members"),
999 : N_("net groupmap listmem\n"
1000 : " List foreign alias members")
1001 : },
1002 : {
1003 : "memberships",
1004 : net_groupmap_memberships,
1005 : NET_TRANSPORT_LOCAL,
1006 : N_("List foreign group memberships"),
1007 : N_("net groupmap memberships\n"
1008 : " List foreign group memberships")
1009 : },
1010 : {
1011 : "list",
1012 : net_groupmap_list,
1013 : NET_TRANSPORT_LOCAL,
1014 : N_("List current group map"),
1015 : N_("net groupmap list\n"
1016 : " List current group map")
1017 : },
1018 : {NULL, NULL, 0, NULL, NULL}
1019 : };
1020 :
1021 348 : return net_run_function(c,argc, argv, "net groupmap", func);
1022 : }
1023 :
|