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) Volker Lendecke 2006.
7 : * Copyright (C) Gerald Carter 2006.
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 : #include "includes.h"
24 : #include "system/passwd.h"
25 : #include "passdb.h"
26 : #include "groupdb/mapping.h"
27 : #include "../libcli/security/security.h"
28 : #include "lib/winbind_util.h"
29 : #include <tdb.h>
30 : #include "groupdb/mapping_tdb.h"
31 : #include "lib/util/smb_strtox.h"
32 :
33 : static const struct mapping_backend *backend;
34 :
35 : /*
36 : initialise a group mapping backend
37 : */
38 374734 : static bool init_group_mapping(void)
39 : {
40 374734 : if (backend != NULL) {
41 : /* already initialised */
42 373163 : return True;
43 : }
44 :
45 1526 : backend = groupdb_tdb_init();
46 :
47 1526 : return backend != NULL;
48 : }
49 :
50 : /****************************************************************************
51 : initialise first time the mapping list
52 : ****************************************************************************/
53 463 : NTSTATUS add_initial_entry(gid_t gid, const char *sid, enum lsa_SidType sid_name_use, const char *nt_name, const char *comment)
54 : {
55 0 : NTSTATUS status;
56 0 : GROUP_MAP *map;
57 :
58 463 : if(!init_group_mapping()) {
59 0 : DEBUG(0,("failed to initialize group mapping\n"));
60 0 : return NT_STATUS_UNSUCCESSFUL;
61 : }
62 :
63 463 : map = talloc_zero(NULL, GROUP_MAP);
64 463 : if (!map) {
65 0 : return NT_STATUS_NO_MEMORY;
66 : }
67 :
68 463 : map->gid=gid;
69 463 : if (!string_to_sid(&map->sid, sid)) {
70 0 : DEBUG(0, ("string_to_sid failed: %s\n", sid));
71 0 : status = NT_STATUS_UNSUCCESSFUL;
72 0 : goto done;
73 : }
74 :
75 463 : map->sid_name_use=sid_name_use;
76 463 : map->nt_name = talloc_strdup(map, nt_name);
77 463 : if (!map->nt_name) {
78 0 : status = NT_STATUS_NO_MEMORY;
79 0 : goto done;
80 : }
81 :
82 463 : if (comment) {
83 161 : map->comment = talloc_strdup(map, comment);
84 : } else {
85 302 : map->comment = talloc_strdup(map, "");
86 : }
87 463 : if (!map->comment) {
88 0 : status = NT_STATUS_NO_MEMORY;
89 0 : goto done;
90 : }
91 :
92 463 : status = pdb_add_group_mapping_entry(map);
93 :
94 463 : done:
95 463 : TALLOC_FREE(map);
96 463 : return status;
97 : }
98 :
99 47370 : static NTSTATUS alias_memberships(const struct dom_sid *members, size_t num_members,
100 : struct dom_sid **sids, size_t *num)
101 : {
102 0 : size_t i;
103 :
104 47370 : *num = 0;
105 47370 : *sids = NULL;
106 :
107 365520 : for (i=0; i<num_members; i++) {
108 318150 : NTSTATUS status = backend->one_alias_membership(&members[i], sids, num);
109 318150 : if (!NT_STATUS_IS_OK(status))
110 0 : return status;
111 : }
112 47370 : return NT_STATUS_OK;
113 : }
114 :
115 : struct aliasmem_closure {
116 : const struct dom_sid *alias;
117 : struct dom_sid **sids;
118 : size_t *num;
119 : };
120 :
121 :
122 :
123 : /*
124 : *
125 : * High level functions
126 : * better to use them than the lower ones.
127 : *
128 : * we are checking if the group is in the mapping file
129 : * and if the group is an existing unix group
130 : *
131 : */
132 :
133 : /* get a domain group from it's SID */
134 :
135 312 : bool get_domain_group_from_sid(struct dom_sid sid, GROUP_MAP *map)
136 : {
137 0 : struct group *grp;
138 0 : bool ret;
139 :
140 312 : if(!init_group_mapping()) {
141 0 : DEBUG(0,("failed to initialize group mapping\n"));
142 0 : return(False);
143 : }
144 :
145 312 : DEBUG(10, ("get_domain_group_from_sid\n"));
146 :
147 : /* if the group is NOT in the database, it CAN NOT be a domain group */
148 :
149 312 : become_root();
150 312 : ret = pdb_getgrsid(map, sid);
151 312 : unbecome_root();
152 :
153 : /* special case check for rid 513 */
154 :
155 312 : if ( !ret ) {
156 0 : uint32_t rid;
157 :
158 0 : sid_peek_rid( &sid, &rid );
159 :
160 0 : if ( rid == DOMAIN_RID_USERS ) {
161 0 : map->nt_name = talloc_strdup(map, "None");
162 0 : if (!map->nt_name) {
163 0 : return false;
164 : }
165 0 : map->comment = talloc_strdup(map, "Ordinary Users");
166 0 : if (!map->comment) {
167 0 : return false;
168 : }
169 0 : sid_copy( &map->sid, &sid );
170 0 : map->sid_name_use = SID_NAME_DOM_GRP;
171 0 : map->gid = (gid_t)-1;
172 0 : return True;
173 : }
174 0 : return False;
175 : }
176 :
177 312 : DEBUG(10, ("get_domain_group_from_sid: SID found in passdb\n"));
178 :
179 : /* if it's not a domain group, continue */
180 312 : if (map->sid_name_use!=SID_NAME_DOM_GRP) {
181 0 : return False;
182 : }
183 :
184 312 : DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n"));
185 :
186 312 : if (map->gid==-1) {
187 0 : return False;
188 : }
189 :
190 312 : DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n",(unsigned long)map->gid));
191 :
192 312 : grp = getgrgid(map->gid);
193 312 : if ( !grp ) {
194 0 : DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n"));
195 0 : return False;
196 : }
197 :
198 312 : DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX security\n"));
199 :
200 312 : return True;
201 : }
202 :
203 : /****************************************************************************
204 : Create a UNIX group on demand.
205 : ****************************************************************************/
206 :
207 302 : int smb_create_group(const char *unix_group, gid_t *new_gid)
208 : {
209 0 : const struct loadparm_substitution *lp_sub =
210 302 : loadparm_s3_global_substitution();
211 302 : char *add_script = NULL;
212 302 : int ret = -1;
213 302 : int fd = 0;
214 302 : int error = 0;
215 :
216 302 : *new_gid = 0;
217 :
218 : /* defer to scripts */
219 :
220 302 : if ( *lp_add_group_script(talloc_tos(), lp_sub) ) {
221 302 : TALLOC_CTX *ctx = talloc_tos();
222 :
223 302 : add_script = talloc_strdup(ctx,
224 302 : lp_add_group_script(ctx, lp_sub));
225 302 : if (!add_script) {
226 0 : return -1;
227 : }
228 302 : add_script = talloc_string_sub(ctx,
229 : add_script, "%g", unix_group);
230 302 : if (!add_script) {
231 0 : return -1;
232 : }
233 :
234 302 : ret = smbrun(add_script, &fd, NULL);
235 302 : DEBUG(ret ? 0 : 3,("smb_create_group: Running the command `%s' gave %d\n",add_script,ret));
236 302 : if (ret == 0) {
237 302 : smb_nscd_flush_group_cache();
238 : }
239 302 : if (ret != 0)
240 0 : return ret;
241 :
242 302 : if (fd != 0) {
243 0 : fstring output;
244 0 : ssize_t nread;
245 :
246 302 : *new_gid = 0;
247 :
248 302 : nread = read(fd, output, sizeof(output)-1);
249 302 : if (nread > 0) {
250 0 : output[nread] = '\0';
251 0 : *new_gid = (gid_t)smb_strtoul(output,
252 : NULL,
253 : 10,
254 : &error,
255 : SMB_STR_STANDARD);
256 0 : if (error != 0) {
257 0 : *new_gid = 0;
258 0 : close(fd);
259 0 : return -1;
260 : }
261 : }
262 :
263 302 : close(fd);
264 : }
265 :
266 : }
267 :
268 302 : if (*new_gid == 0) {
269 302 : struct group *grp = getgrnam(unix_group);
270 :
271 302 : if (grp != NULL)
272 302 : *new_gid = grp->gr_gid;
273 : }
274 :
275 302 : return ret;
276 : }
277 :
278 : /****************************************************************************
279 : Delete a UNIX group on demand.
280 : ****************************************************************************/
281 :
282 2 : int smb_delete_group(const char *unix_group)
283 : {
284 0 : const struct loadparm_substitution *lp_sub =
285 2 : loadparm_s3_global_substitution();
286 2 : char *del_script = NULL;
287 2 : int ret = -1;
288 :
289 : /* defer to scripts */
290 :
291 2 : if ( *lp_delete_group_script(talloc_tos(), lp_sub) ) {
292 2 : TALLOC_CTX *ctx = talloc_tos();
293 :
294 2 : del_script = talloc_strdup(ctx,
295 2 : lp_delete_group_script(ctx, lp_sub));
296 2 : if (!del_script) {
297 0 : return -1;
298 : }
299 2 : del_script = talloc_string_sub(ctx,
300 : del_script, "%g", unix_group);
301 2 : if (!del_script) {
302 0 : return -1;
303 : }
304 2 : ret = smbrun(del_script, NULL, NULL);
305 2 : DEBUG(ret ? 0 : 3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
306 2 : if (ret == 0) {
307 2 : smb_nscd_flush_group_cache();
308 : }
309 2 : return ret;
310 : }
311 :
312 0 : return -1;
313 : }
314 :
315 : /****************************************************************************
316 : Set a user's primary UNIX group.
317 : ****************************************************************************/
318 :
319 0 : int smb_set_primary_group(const char *unix_group, const char* unix_user)
320 : {
321 0 : const struct loadparm_substitution *lp_sub =
322 0 : loadparm_s3_global_substitution();
323 0 : char *add_script = NULL;
324 0 : int ret = -1;
325 :
326 : /* defer to scripts */
327 :
328 0 : if ( *lp_set_primary_group_script(talloc_tos(), lp_sub) ) {
329 0 : TALLOC_CTX *ctx = talloc_tos();
330 :
331 0 : add_script = talloc_strdup(ctx,
332 0 : lp_set_primary_group_script(ctx, lp_sub));
333 0 : if (!add_script) {
334 0 : return -1;
335 : }
336 0 : add_script = talloc_all_string_sub(ctx,
337 : add_script, "%g", unix_group);
338 0 : if (!add_script) {
339 0 : return -1;
340 : }
341 0 : add_script = talloc_string_sub(ctx,
342 : add_script, "%u", unix_user);
343 0 : if (!add_script) {
344 0 : return -1;
345 : }
346 0 : ret = smbrun(add_script, NULL, NULL);
347 0 : flush_pwnam_cache();
348 0 : DEBUG(ret ? 0 : 3,("smb_set_primary_group: "
349 : "Running the command `%s' gave %d\n",add_script,ret));
350 0 : if (ret == 0) {
351 0 : smb_nscd_flush_group_cache();
352 : }
353 0 : return ret;
354 : }
355 :
356 0 : return -1;
357 : }
358 :
359 : /****************************************************************************
360 : Add a user to a UNIX group.
361 : ****************************************************************************/
362 :
363 2 : int smb_add_user_group(const char *unix_group, const char *unix_user)
364 : {
365 0 : const struct loadparm_substitution *lp_sub =
366 2 : loadparm_s3_global_substitution();
367 2 : char *add_script = NULL;
368 2 : int ret = -1;
369 :
370 : /* defer to scripts */
371 :
372 2 : if ( *lp_add_user_to_group_script(talloc_tos(), lp_sub) ) {
373 2 : TALLOC_CTX *ctx = talloc_tos();
374 :
375 2 : add_script = talloc_strdup(ctx,
376 2 : lp_add_user_to_group_script(ctx, lp_sub));
377 2 : if (!add_script) {
378 0 : return -1;
379 : }
380 2 : add_script = talloc_string_sub(ctx,
381 : add_script, "%g", unix_group);
382 2 : if (!add_script) {
383 0 : return -1;
384 : }
385 2 : add_script = talloc_string_sub2(ctx,
386 : add_script, "%u", unix_user, true, false, true);
387 2 : if (!add_script) {
388 0 : return -1;
389 : }
390 2 : ret = smbrun(add_script, NULL, NULL);
391 2 : DEBUG(ret ? 0 : 3,("smb_add_user_group: Running the command `%s' gave %d\n",add_script,ret));
392 2 : if (ret == 0) {
393 2 : smb_nscd_flush_group_cache();
394 : }
395 2 : return ret;
396 : }
397 :
398 0 : return -1;
399 : }
400 :
401 : /****************************************************************************
402 : Delete a user from a UNIX group
403 : ****************************************************************************/
404 :
405 2 : int smb_delete_user_group(const char *unix_group, const char *unix_user)
406 : {
407 0 : const struct loadparm_substitution *lp_sub =
408 2 : loadparm_s3_global_substitution();
409 2 : char *del_script = NULL;
410 2 : int ret = -1;
411 :
412 : /* defer to scripts */
413 :
414 2 : if ( *lp_delete_user_from_group_script(talloc_tos(), lp_sub) ) {
415 2 : TALLOC_CTX *ctx = talloc_tos();
416 :
417 2 : del_script = talloc_strdup(ctx,
418 2 : lp_delete_user_from_group_script(ctx, lp_sub));
419 2 : if (!del_script) {
420 0 : return -1;
421 : }
422 2 : del_script = talloc_string_sub(ctx,
423 : del_script, "%g", unix_group);
424 2 : if (!del_script) {
425 0 : return -1;
426 : }
427 2 : del_script = talloc_string_sub2(ctx,
428 : del_script, "%u", unix_user, true, false, true);
429 2 : if (!del_script) {
430 0 : return -1;
431 : }
432 2 : ret = smbrun(del_script, NULL, NULL);
433 2 : DEBUG(ret ? 0 : 3,("smb_delete_user_group: Running the command `%s' gave %d\n",del_script,ret));
434 2 : if (ret == 0) {
435 2 : smb_nscd_flush_group_cache();
436 : }
437 2 : return ret;
438 : }
439 :
440 0 : return -1;
441 : }
442 :
443 :
444 103118 : NTSTATUS pdb_default_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
445 : struct dom_sid sid)
446 : {
447 103119 : if (!init_group_mapping()) {
448 0 : DEBUG(0,("failed to initialize group mapping\n"));
449 0 : return NT_STATUS_UNSUCCESSFUL;
450 : }
451 103118 : return backend->get_group_map_from_sid(sid, map) ?
452 103118 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
453 : }
454 :
455 220335 : NTSTATUS pdb_default_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
456 : gid_t gid)
457 : {
458 220335 : if (!init_group_mapping()) {
459 0 : DEBUG(0,("failed to initialize group mapping\n"));
460 0 : return NT_STATUS_UNSUCCESSFUL;
461 : }
462 220335 : return backend->get_group_map_from_gid(gid, map) ?
463 220335 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
464 : }
465 :
466 2156 : NTSTATUS pdb_default_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
467 : const char *name)
468 : {
469 2156 : if (!init_group_mapping()) {
470 0 : DEBUG(0,("failed to initialize group mapping\n"));
471 0 : return NT_STATUS_UNSUCCESSFUL;
472 : }
473 2156 : return backend->get_group_map_from_ntname(name, map) ?
474 2156 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
475 : }
476 :
477 800 : NTSTATUS pdb_default_add_group_mapping_entry(struct pdb_methods *methods,
478 : GROUP_MAP *map)
479 : {
480 800 : if (!init_group_mapping()) {
481 0 : DEBUG(0,("failed to initialize group mapping\n"));
482 0 : return NT_STATUS_UNSUCCESSFUL;
483 : }
484 800 : return backend->add_mapping_entry(map, TDB_INSERT) ?
485 800 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
486 : }
487 :
488 0 : NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods,
489 : GROUP_MAP *map)
490 : {
491 0 : if (!init_group_mapping()) {
492 0 : DEBUG(0,("failed to initialize group mapping\n"));
493 0 : return NT_STATUS_UNSUCCESSFUL;
494 : }
495 0 : return backend->add_mapping_entry(map, TDB_REPLACE) ?
496 0 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
497 : }
498 :
499 18 : NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods,
500 : struct dom_sid sid)
501 : {
502 18 : if (!init_group_mapping()) {
503 0 : DEBUG(0,("failed to initialize group mapping\n"));
504 0 : return NT_STATUS_UNSUCCESSFUL;
505 : }
506 18 : return backend->group_map_remove(&sid) ?
507 18 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
508 : }
509 :
510 30 : NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods,
511 : const struct dom_sid *sid,
512 : enum lsa_SidType sid_name_use,
513 : GROUP_MAP ***pp_rmap,
514 : size_t *p_num_entries,
515 : bool unix_only)
516 : {
517 34 : if (!init_group_mapping()) {
518 0 : DEBUG(0,("failed to initialize group mapping\n"));
519 0 : return NT_STATUS_UNSUCCESSFUL;
520 : }
521 30 : return backend->enum_group_mapping(sid, sid_name_use, pp_rmap, p_num_entries, unix_only) ?
522 30 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
523 : }
524 :
525 302 : NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
526 : const char *name, uint32_t *rid)
527 : {
528 0 : struct dom_sid sid;
529 0 : enum lsa_SidType type;
530 0 : uint32_t new_rid;
531 0 : gid_t gid;
532 0 : bool exists;
533 0 : GROUP_MAP *map;
534 0 : TALLOC_CTX *mem_ctx;
535 0 : NTSTATUS status;
536 :
537 302 : DEBUG(10, ("Trying to create alias %s\n", name));
538 :
539 302 : mem_ctx = talloc_new(NULL);
540 302 : if (mem_ctx == NULL) {
541 0 : return NT_STATUS_NO_MEMORY;
542 : }
543 :
544 302 : exists = lookup_name(mem_ctx, name, LOOKUP_NAME_LOCAL,
545 : NULL, NULL, &sid, &type);
546 :
547 302 : if (exists) {
548 0 : status = NT_STATUS_ALIAS_EXISTS;
549 0 : goto done;
550 : }
551 :
552 302 : if (!pdb_new_rid(&new_rid)) {
553 0 : DEBUG(0, ("Could not allocate a RID.\n"));
554 0 : status = NT_STATUS_ACCESS_DENIED;
555 0 : goto done;
556 : }
557 :
558 302 : sid_compose(&sid, get_global_sam_sid(), new_rid);
559 :
560 302 : if (!winbind_allocate_gid(&gid)) {
561 0 : DEBUG(3, ("Could not get a gid out of winbind - "
562 : "wasted a rid :-(\n"));
563 0 : status = NT_STATUS_ACCESS_DENIED;
564 0 : goto done;
565 : }
566 :
567 302 : DEBUG(10, ("Creating alias %s with gid %u and rid %u\n",
568 : name, (unsigned int)gid, (unsigned int)new_rid));
569 :
570 302 : map = talloc_zero(mem_ctx, GROUP_MAP);
571 302 : if (!map) {
572 0 : status = NT_STATUS_NO_MEMORY;
573 0 : goto done;
574 : }
575 :
576 302 : map->gid = gid;
577 302 : sid_copy(&map->sid, &sid);
578 302 : map->sid_name_use = SID_NAME_ALIAS;
579 302 : map->nt_name = talloc_strdup(map, name);
580 302 : if (!map->nt_name) {
581 0 : status = NT_STATUS_NO_MEMORY;
582 0 : goto done;
583 : }
584 302 : map->comment = talloc_strdup(map, "");
585 302 : if (!map->comment) {
586 0 : status = NT_STATUS_NO_MEMORY;
587 0 : goto done;
588 : }
589 :
590 302 : status = pdb_add_group_mapping_entry(map);
591 :
592 302 : if (!NT_STATUS_IS_OK(status)) {
593 0 : DEBUG(0, ("Could not add group mapping entry for alias %s "
594 : "(%s)\n", name, nt_errstr(status)));
595 0 : goto done;
596 : }
597 :
598 302 : *rid = new_rid;
599 :
600 302 : done:
601 302 : TALLOC_FREE(mem_ctx);
602 302 : return status;
603 : }
604 :
605 2 : NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods,
606 : const struct dom_sid *sid)
607 : {
608 2 : return pdb_delete_group_mapping_entry(*sid);
609 : }
610 :
611 69936 : NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods,
612 : const struct dom_sid *sid,
613 : struct acct_info *info)
614 : {
615 69936 : NTSTATUS status = NT_STATUS_OK;
616 0 : GROUP_MAP *map;
617 :
618 69936 : map = talloc_zero(NULL, GROUP_MAP);
619 69936 : if (!map) {
620 0 : return NT_STATUS_NO_MEMORY;
621 : }
622 :
623 69936 : if (!pdb_getgrsid(map, *sid)) {
624 34484 : status = NT_STATUS_NO_SUCH_ALIAS;
625 34484 : goto done;
626 : }
627 :
628 35452 : if ((map->sid_name_use != SID_NAME_ALIAS) &&
629 8 : (map->sid_name_use != SID_NAME_WKN_GRP)) {
630 0 : struct dom_sid_buf buf;
631 0 : DEBUG(2, ("%s is a %s, expected an alias\n",
632 : dom_sid_str_buf(sid, &buf),
633 : sid_type_lookup(map->sid_name_use)));
634 0 : status = NT_STATUS_NO_SUCH_ALIAS;
635 0 : goto done;
636 : }
637 :
638 35452 : info->acct_name = talloc_move(info, &map->nt_name);
639 35452 : if (!info->acct_name) {
640 0 : status = NT_STATUS_NO_MEMORY;
641 0 : goto done;
642 : }
643 35452 : info->acct_desc = talloc_move(info, &map->comment);
644 35452 : if (!info->acct_desc) {
645 0 : status = NT_STATUS_NO_MEMORY;
646 0 : goto done;
647 : }
648 35452 : sid_peek_rid(&map->sid, &info->rid);
649 :
650 69936 : done:
651 69936 : TALLOC_FREE(map);
652 69936 : return status;
653 : }
654 :
655 0 : NTSTATUS pdb_default_set_aliasinfo(struct pdb_methods *methods,
656 : const struct dom_sid *sid,
657 : struct acct_info *info)
658 : {
659 0 : NTSTATUS status;
660 0 : GROUP_MAP *map;
661 :
662 0 : map = talloc_zero(NULL, GROUP_MAP);
663 0 : if (!map) {
664 0 : return NT_STATUS_NO_MEMORY;
665 : }
666 :
667 0 : if (!pdb_getgrsid(map, *sid)) {
668 0 : status = NT_STATUS_NO_SUCH_ALIAS;
669 0 : goto done;
670 : }
671 :
672 0 : map->nt_name = talloc_strdup(map, info->acct_name);
673 0 : if (!map->nt_name) {
674 0 : status = NT_STATUS_NO_MEMORY;
675 0 : goto done;
676 : }
677 0 : map->comment = talloc_strdup(map, info->acct_desc);
678 0 : if (!map->comment) {
679 0 : status = NT_STATUS_NO_MEMORY;
680 0 : goto done;
681 : }
682 :
683 0 : status = pdb_update_group_mapping_entry(map);
684 :
685 0 : done:
686 0 : TALLOC_FREE(map);
687 0 : return status;
688 : }
689 :
690 74 : NTSTATUS pdb_default_add_aliasmem(struct pdb_methods *methods,
691 : const struct dom_sid *alias, const struct dom_sid *member)
692 : {
693 74 : if (!init_group_mapping()) {
694 0 : DEBUG(0,("failed to initialize group mapping\n"));
695 0 : return NT_STATUS_UNSUCCESSFUL;
696 : }
697 74 : return backend->add_aliasmem(alias, member);
698 : }
699 :
700 20 : NTSTATUS pdb_default_del_aliasmem(struct pdb_methods *methods,
701 : const struct dom_sid *alias, const struct dom_sid *member)
702 : {
703 20 : if (!init_group_mapping()) {
704 0 : DEBUG(0,("failed to initialize group mapping\n"));
705 0 : return NT_STATUS_UNSUCCESSFUL;
706 : }
707 20 : return backend->del_aliasmem(alias, member);
708 : }
709 :
710 38 : NTSTATUS pdb_default_enum_aliasmem(struct pdb_methods *methods,
711 : const struct dom_sid *alias, TALLOC_CTX *mem_ctx,
712 : struct dom_sid **pp_members, size_t *p_num_members)
713 : {
714 38 : if (!init_group_mapping()) {
715 0 : DEBUG(0,("failed to initialize group mapping\n"));
716 0 : return NT_STATUS_UNSUCCESSFUL;
717 : }
718 38 : return backend->enum_aliasmem(alias, mem_ctx, pp_members,
719 : p_num_members);
720 : }
721 :
722 47370 : NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
723 : TALLOC_CTX *mem_ctx,
724 : const struct dom_sid *domain_sid,
725 : const struct dom_sid *members,
726 : size_t num_members,
727 : uint32_t **pp_alias_rids,
728 : size_t *p_num_alias_rids)
729 : {
730 0 : struct dom_sid *alias_sids;
731 0 : size_t i, num_alias_sids;
732 0 : NTSTATUS result;
733 :
734 47370 : if (!init_group_mapping()) {
735 0 : DEBUG(0,("failed to initialize group mapping\n"));
736 0 : return NT_STATUS_UNSUCCESSFUL;
737 : }
738 :
739 47370 : alias_sids = NULL;
740 47370 : num_alias_sids = 0;
741 :
742 47370 : result = alias_memberships(members, num_members,
743 : &alias_sids, &num_alias_sids);
744 :
745 47370 : if (!NT_STATUS_IS_OK(result))
746 0 : return result;
747 :
748 47370 : *p_num_alias_rids = 0;
749 :
750 47370 : if (num_alias_sids == 0) {
751 36414 : TALLOC_FREE(alias_sids);
752 36414 : return NT_STATUS_OK;
753 : }
754 :
755 10956 : *pp_alias_rids = talloc_array(mem_ctx, uint32_t, num_alias_sids);
756 10956 : if (*pp_alias_rids == NULL)
757 0 : return NT_STATUS_NO_MEMORY;
758 :
759 23784 : for (i=0; i<num_alias_sids; i++) {
760 12828 : if (!sid_peek_check_rid(domain_sid, &alias_sids[i],
761 12828 : &(*pp_alias_rids)[*p_num_alias_rids]))
762 6414 : continue;
763 6414 : *p_num_alias_rids += 1;
764 : }
765 :
766 10956 : TALLOC_FREE(alias_sids);
767 :
768 10956 : return NT_STATUS_OK;
769 : }
770 :
771 : /**********************************************************************
772 : no ops for passdb backends that don't implement group mapping
773 : *********************************************************************/
774 :
775 0 : NTSTATUS pdb_nop_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
776 : struct dom_sid sid)
777 : {
778 0 : return NT_STATUS_UNSUCCESSFUL;
779 : }
780 :
781 0 : NTSTATUS pdb_nop_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
782 : gid_t gid)
783 : {
784 0 : return NT_STATUS_UNSUCCESSFUL;
785 : }
786 :
787 0 : NTSTATUS pdb_nop_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
788 : const char *name)
789 : {
790 0 : return NT_STATUS_UNSUCCESSFUL;
791 : }
792 :
793 0 : NTSTATUS pdb_nop_add_group_mapping_entry(struct pdb_methods *methods,
794 : GROUP_MAP *map)
795 : {
796 0 : return NT_STATUS_UNSUCCESSFUL;
797 : }
798 :
799 0 : NTSTATUS pdb_nop_update_group_mapping_entry(struct pdb_methods *methods,
800 : GROUP_MAP *map)
801 : {
802 0 : return NT_STATUS_UNSUCCESSFUL;
803 : }
804 :
805 0 : NTSTATUS pdb_nop_delete_group_mapping_entry(struct pdb_methods *methods,
806 : struct dom_sid sid)
807 : {
808 0 : return NT_STATUS_UNSUCCESSFUL;
809 : }
810 :
811 0 : NTSTATUS pdb_nop_enum_group_mapping(struct pdb_methods *methods,
812 : enum lsa_SidType sid_name_use,
813 : GROUP_MAP **rmap, size_t *num_entries,
814 : bool unix_only)
815 : {
816 0 : return NT_STATUS_UNSUCCESSFUL;
817 : }
818 :
819 : /**
820 : * @brief Add a new group mapping
821 : *
822 : * @param[in] gid gid to use to store the mapping. If gid is 0,
823 : * new gid will be allocated from winbind
824 : *
825 : * @return Normal NTSTATUS return
826 : */
827 167 : NTSTATUS pdb_create_builtin_alias(uint32_t rid, gid_t gid)
828 : {
829 0 : struct dom_sid sid;
830 0 : enum lsa_SidType type;
831 0 : gid_t gidformap;
832 0 : GROUP_MAP *map;
833 0 : NTSTATUS status;
834 167 : const char *name = NULL;
835 :
836 167 : DEBUG(10, ("Trying to create builtin alias %d\n", rid));
837 :
838 167 : if ( !sid_compose( &sid, &global_sid_Builtin, rid ) ) {
839 0 : return NT_STATUS_NO_SUCH_ALIAS;
840 : }
841 :
842 : /* use map as overall temp mem context */
843 167 : map = talloc_zero(NULL, GROUP_MAP);
844 167 : if (!map) {
845 0 : return NT_STATUS_NO_MEMORY;
846 : }
847 :
848 167 : if (!lookup_sid(map, &sid, NULL, &name, &type)) {
849 0 : status = NT_STATUS_NO_SUCH_ALIAS;
850 0 : goto done;
851 : }
852 :
853 167 : if (gid == 0) {
854 167 : if (!winbind_allocate_gid(&gidformap)) {
855 132 : DEBUG(3, ("pdb_create_builtin_alias: Could not get a "
856 : "gid out of winbind\n"));
857 132 : status = NT_STATUS_ACCESS_DENIED;
858 132 : goto done;
859 : }
860 : } else {
861 0 : gidformap = gid;
862 : }
863 :
864 35 : DEBUG(10, ("Creating alias %s with gid %u\n", name,
865 : (unsigned) gidformap));
866 :
867 35 : map->gid = gidformap;
868 35 : sid_copy(&map->sid, &sid);
869 35 : map->sid_name_use = SID_NAME_ALIAS;
870 35 : map->nt_name = talloc_strdup(map, name);
871 35 : if (!map->nt_name) {
872 0 : status = NT_STATUS_NO_MEMORY;
873 0 : goto done;
874 : }
875 35 : map->comment = talloc_strdup(map, "");
876 35 : if (!map->comment) {
877 0 : status = NT_STATUS_NO_MEMORY;
878 0 : goto done;
879 : }
880 :
881 35 : status = pdb_add_group_mapping_entry(map);
882 :
883 35 : if (!NT_STATUS_IS_OK(status)) {
884 0 : DEBUG(0, ("pdb_create_builtin_alias: Could not add group mapping entry for alias %d "
885 : "(%s)\n", rid, nt_errstr(status)));
886 : }
887 :
888 35 : done:
889 167 : TALLOC_FREE(map);
890 167 : return status;
891 : }
892 :
893 :
|