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 370375 : static bool init_group_mapping(void)
39 : {
40 370375 : if (backend != NULL) {
41 : /* already initialised */
42 368879 : return True;
43 : }
44 :
45 1451 : backend = groupdb_tdb_init();
46 :
47 1451 : return backend != NULL;
48 : }
49 :
50 : /****************************************************************************
51 : initialise first time the mapping list
52 : ****************************************************************************/
53 452 : 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 452 : if(!init_group_mapping()) {
59 0 : DEBUG(0,("failed to initialize group mapping\n"));
60 0 : return NT_STATUS_UNSUCCESSFUL;
61 : }
62 :
63 452 : map = talloc_zero(NULL, GROUP_MAP);
64 452 : if (!map) {
65 0 : return NT_STATUS_NO_MEMORY;
66 : }
67 :
68 452 : map->gid=gid;
69 452 : 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 452 : map->sid_name_use=sid_name_use;
76 452 : map->nt_name = talloc_strdup(map, nt_name);
77 452 : if (!map->nt_name) {
78 0 : status = NT_STATUS_NO_MEMORY;
79 0 : goto done;
80 : }
81 :
82 452 : if (comment) {
83 149 : map->comment = talloc_strdup(map, comment);
84 : } else {
85 303 : map->comment = talloc_strdup(map, "");
86 : }
87 452 : if (!map->comment) {
88 0 : status = NT_STATUS_NO_MEMORY;
89 0 : goto done;
90 : }
91 :
92 452 : status = pdb_add_group_mapping_entry(map);
93 :
94 452 : done:
95 452 : TALLOC_FREE(map);
96 452 : return status;
97 : }
98 :
99 46778 : 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 46778 : *num = 0;
105 46778 : *sids = NULL;
106 :
107 360804 : for (i=0; i<num_members; i++) {
108 314026 : NTSTATUS status = backend->one_alias_membership(&members[i], sids, num);
109 314026 : if (!NT_STATUS_IS_OK(status))
110 0 : return status;
111 : }
112 46778 : 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 345 : 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 345 : if(!init_group_mapping()) {
141 0 : DEBUG(0,("failed to initialize group mapping\n"));
142 0 : return(False);
143 : }
144 :
145 345 : 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 345 : become_root();
150 345 : ret = pdb_getgrsid(map, sid);
151 345 : unbecome_root();
152 :
153 : /* special case check for rid 513 */
154 :
155 345 : 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 345 : DEBUG(10, ("get_domain_group_from_sid: SID found in passdb\n"));
178 :
179 : /* if it's not a domain group, continue */
180 345 : if (map->sid_name_use!=SID_NAME_DOM_GRP) {
181 0 : return False;
182 : }
183 :
184 345 : DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n"));
185 :
186 345 : if (map->gid==-1) {
187 0 : return False;
188 : }
189 :
190 345 : DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n",(unsigned long)map->gid));
191 :
192 345 : grp = getgrgid(map->gid);
193 345 : 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 345 : DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX security\n"));
199 :
200 345 : return True;
201 : }
202 :
203 : /****************************************************************************
204 : Create a UNIX group on demand.
205 : ****************************************************************************/
206 :
207 303 : int smb_create_group(const char *unix_group, gid_t *new_gid)
208 : {
209 0 : const struct loadparm_substitution *lp_sub =
210 303 : loadparm_s3_global_substitution();
211 303 : char *add_script = NULL;
212 303 : int ret = -1;
213 303 : int fd = 0;
214 303 : int error = 0;
215 :
216 303 : *new_gid = 0;
217 :
218 : /* defer to scripts */
219 :
220 303 : if ( *lp_add_group_script(talloc_tos(), lp_sub) ) {
221 303 : TALLOC_CTX *ctx = talloc_tos();
222 :
223 303 : add_script = talloc_strdup(ctx,
224 303 : lp_add_group_script(ctx, lp_sub));
225 303 : if (!add_script) {
226 0 : return -1;
227 : }
228 303 : add_script = talloc_string_sub(ctx,
229 : add_script, "%g", unix_group);
230 303 : if (!add_script) {
231 0 : return -1;
232 : }
233 :
234 303 : ret = smbrun(add_script, &fd, NULL);
235 303 : DEBUG(ret ? 0 : 3,("smb_create_group: Running the command `%s' gave %d\n",add_script,ret));
236 303 : if (ret == 0) {
237 303 : smb_nscd_flush_group_cache();
238 : }
239 303 : if (ret != 0)
240 0 : return ret;
241 :
242 303 : if (fd != 0) {
243 0 : fstring output;
244 0 : ssize_t nread;
245 :
246 303 : *new_gid = 0;
247 :
248 303 : nread = read(fd, output, sizeof(output)-1);
249 303 : 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 303 : close(fd);
264 : }
265 :
266 : }
267 :
268 303 : if (*new_gid == 0) {
269 303 : struct group *grp = getgrnam(unix_group);
270 :
271 303 : if (grp != NULL)
272 303 : *new_gid = grp->gr_gid;
273 : }
274 :
275 303 : return ret;
276 : }
277 :
278 : /****************************************************************************
279 : Delete a UNIX group on demand.
280 : ****************************************************************************/
281 :
282 3 : int smb_delete_group(const char *unix_group)
283 : {
284 0 : const struct loadparm_substitution *lp_sub =
285 3 : loadparm_s3_global_substitution();
286 3 : char *del_script = NULL;
287 3 : int ret = -1;
288 :
289 : /* defer to scripts */
290 :
291 3 : if ( *lp_delete_group_script(talloc_tos(), lp_sub) ) {
292 3 : TALLOC_CTX *ctx = talloc_tos();
293 :
294 3 : del_script = talloc_strdup(ctx,
295 3 : lp_delete_group_script(ctx, lp_sub));
296 3 : if (!del_script) {
297 0 : return -1;
298 : }
299 3 : del_script = talloc_string_sub(ctx,
300 : del_script, "%g", unix_group);
301 3 : if (!del_script) {
302 0 : return -1;
303 : }
304 3 : ret = smbrun(del_script, NULL, NULL);
305 3 : DEBUG(ret ? 0 : 3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
306 3 : if (ret == 0) {
307 3 : smb_nscd_flush_group_cache();
308 : }
309 3 : 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 4 : int smb_add_user_group(const char *unix_group, const char *unix_user)
364 : {
365 0 : const struct loadparm_substitution *lp_sub =
366 4 : loadparm_s3_global_substitution();
367 4 : char *add_script = NULL;
368 4 : int ret = -1;
369 :
370 : /* defer to scripts */
371 :
372 4 : if ( *lp_add_user_to_group_script(talloc_tos(), lp_sub) ) {
373 4 : TALLOC_CTX *ctx = talloc_tos();
374 :
375 4 : add_script = talloc_strdup(ctx,
376 4 : lp_add_user_to_group_script(ctx, lp_sub));
377 4 : if (!add_script) {
378 0 : return -1;
379 : }
380 4 : add_script = talloc_string_sub(ctx,
381 : add_script, "%g", unix_group);
382 4 : if (!add_script) {
383 0 : return -1;
384 : }
385 4 : add_script = talloc_string_sub2(ctx,
386 : add_script, "%u", unix_user, true, false, true);
387 4 : if (!add_script) {
388 0 : return -1;
389 : }
390 4 : ret = smbrun(add_script, NULL, NULL);
391 4 : DEBUG(ret ? 0 : 3,("smb_add_user_group: Running the command `%s' gave %d\n",add_script,ret));
392 4 : if (ret == 0) {
393 4 : smb_nscd_flush_group_cache();
394 : }
395 4 : return ret;
396 : }
397 :
398 0 : return -1;
399 : }
400 :
401 : /****************************************************************************
402 : Delete a user from a UNIX group
403 : ****************************************************************************/
404 :
405 3 : int smb_delete_user_group(const char *unix_group, const char *unix_user)
406 : {
407 0 : const struct loadparm_substitution *lp_sub =
408 3 : loadparm_s3_global_substitution();
409 3 : char *del_script = NULL;
410 3 : int ret = -1;
411 :
412 : /* defer to scripts */
413 :
414 3 : if ( *lp_delete_user_from_group_script(talloc_tos(), lp_sub) ) {
415 3 : TALLOC_CTX *ctx = talloc_tos();
416 :
417 3 : del_script = talloc_strdup(ctx,
418 3 : lp_delete_user_from_group_script(ctx, lp_sub));
419 3 : if (!del_script) {
420 0 : return -1;
421 : }
422 3 : del_script = talloc_string_sub(ctx,
423 : del_script, "%g", unix_group);
424 3 : if (!del_script) {
425 0 : return -1;
426 : }
427 3 : del_script = talloc_string_sub2(ctx,
428 : del_script, "%u", unix_user, true, false, true);
429 3 : if (!del_script) {
430 0 : return -1;
431 : }
432 3 : ret = smbrun(del_script, NULL, NULL);
433 3 : DEBUG(ret ? 0 : 3,("smb_delete_user_group: Running the command `%s' gave %d\n",del_script,ret));
434 3 : if (ret == 0) {
435 3 : smb_nscd_flush_group_cache();
436 : }
437 3 : return ret;
438 : }
439 :
440 0 : return -1;
441 : }
442 :
443 :
444 101461 : NTSTATUS pdb_default_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
445 : struct dom_sid sid)
446 : {
447 101462 : if (!init_group_mapping()) {
448 0 : DEBUG(0,("failed to initialize group mapping\n"));
449 0 : return NT_STATUS_UNSUCCESSFUL;
450 : }
451 101461 : return backend->get_group_map_from_sid(sid, map) ?
452 101461 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
453 : }
454 :
455 218129 : NTSTATUS pdb_default_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
456 : gid_t gid)
457 : {
458 218129 : if (!init_group_mapping()) {
459 0 : DEBUG(0,("failed to initialize group mapping\n"));
460 0 : return NT_STATUS_UNSUCCESSFUL;
461 : }
462 218129 : return backend->get_group_map_from_gid(gid, map) ?
463 218129 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
464 : }
465 :
466 2189 : NTSTATUS pdb_default_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
467 : const char *name)
468 : {
469 2189 : if (!init_group_mapping()) {
470 0 : DEBUG(0,("failed to initialize group mapping\n"));
471 0 : return NT_STATUS_UNSUCCESSFUL;
472 : }
473 2189 : return backend->get_group_map_from_ntname(name, map) ?
474 2189 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
475 : }
476 :
477 804 : NTSTATUS pdb_default_add_group_mapping_entry(struct pdb_methods *methods,
478 : GROUP_MAP *map)
479 : {
480 804 : if (!init_group_mapping()) {
481 0 : DEBUG(0,("failed to initialize group mapping\n"));
482 0 : return NT_STATUS_UNSUCCESSFUL;
483 : }
484 804 : return backend->add_mapping_entry(map, TDB_INSERT) ?
485 804 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
486 : }
487 :
488 4 : NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods,
489 : GROUP_MAP *map)
490 : {
491 4 : if (!init_group_mapping()) {
492 0 : DEBUG(0,("failed to initialize group mapping\n"));
493 0 : return NT_STATUS_UNSUCCESSFUL;
494 : }
495 4 : return backend->add_mapping_entry(map, TDB_REPLACE) ?
496 4 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
497 : }
498 :
499 20 : NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods,
500 : struct dom_sid sid)
501 : {
502 20 : if (!init_group_mapping()) {
503 0 : DEBUG(0,("failed to initialize group mapping\n"));
504 0 : return NT_STATUS_UNSUCCESSFUL;
505 : }
506 20 : return backend->group_map_remove(&sid) ?
507 20 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
508 : }
509 :
510 38 : 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 42 : if (!init_group_mapping()) {
518 0 : DEBUG(0,("failed to initialize group mapping\n"));
519 0 : return NT_STATUS_UNSUCCESSFUL;
520 : }
521 38 : return backend->enum_group_mapping(sid, sid_name_use, pp_rmap, p_num_entries, unix_only) ?
522 38 : NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
523 : }
524 :
525 303 : 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 303 : DEBUG(10, ("Trying to create alias %s\n", name));
538 :
539 303 : mem_ctx = talloc_new(NULL);
540 303 : if (mem_ctx == NULL) {
541 0 : return NT_STATUS_NO_MEMORY;
542 : }
543 :
544 303 : exists = lookup_name(mem_ctx, name, LOOKUP_NAME_LOCAL,
545 : NULL, NULL, &sid, &type);
546 :
547 303 : if (exists) {
548 0 : status = NT_STATUS_ALIAS_EXISTS;
549 0 : goto done;
550 : }
551 :
552 303 : 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 303 : sid_compose(&sid, get_global_sam_sid(), new_rid);
559 :
560 303 : 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 303 : DEBUG(10, ("Creating alias %s with gid %u and rid %u\n",
568 : name, (unsigned int)gid, (unsigned int)new_rid));
569 :
570 303 : map = talloc_zero(mem_ctx, GROUP_MAP);
571 303 : if (!map) {
572 0 : status = NT_STATUS_NO_MEMORY;
573 0 : goto done;
574 : }
575 :
576 303 : map->gid = gid;
577 303 : sid_copy(&map->sid, &sid);
578 303 : map->sid_name_use = SID_NAME_ALIAS;
579 303 : map->nt_name = talloc_strdup(map, name);
580 303 : if (!map->nt_name) {
581 0 : status = NT_STATUS_NO_MEMORY;
582 0 : goto done;
583 : }
584 303 : map->comment = talloc_strdup(map, "");
585 303 : if (!map->comment) {
586 0 : status = NT_STATUS_NO_MEMORY;
587 0 : goto done;
588 : }
589 :
590 303 : status = pdb_add_group_mapping_entry(map);
591 :
592 303 : 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 303 : *rid = new_rid;
599 :
600 303 : done:
601 303 : TALLOC_FREE(mem_ctx);
602 303 : return status;
603 : }
604 :
605 3 : NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods,
606 : const struct dom_sid *sid)
607 : {
608 3 : return pdb_delete_group_mapping_entry(*sid);
609 : }
610 :
611 69052 : NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods,
612 : const struct dom_sid *sid,
613 : struct acct_info *info)
614 : {
615 69052 : NTSTATUS status = NT_STATUS_OK;
616 0 : GROUP_MAP *map;
617 :
618 69052 : map = talloc_zero(NULL, GROUP_MAP);
619 69052 : if (!map) {
620 0 : return NT_STATUS_NO_MEMORY;
621 : }
622 :
623 69052 : if (!pdb_getgrsid(map, *sid)) {
624 33596 : status = NT_STATUS_NO_SUCH_ALIAS;
625 33596 : goto done;
626 : }
627 :
628 35456 : 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 35456 : info->acct_name = talloc_move(info, &map->nt_name);
639 35456 : if (!info->acct_name) {
640 0 : status = NT_STATUS_NO_MEMORY;
641 0 : goto done;
642 : }
643 35456 : info->acct_desc = talloc_move(info, &map->comment);
644 35456 : if (!info->acct_desc) {
645 0 : status = NT_STATUS_NO_MEMORY;
646 0 : goto done;
647 : }
648 35456 : sid_peek_rid(&map->sid, &info->rid);
649 :
650 69052 : done:
651 69052 : TALLOC_FREE(map);
652 69052 : return status;
653 : }
654 :
655 1 : 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 1 : map = talloc_zero(NULL, GROUP_MAP);
663 1 : if (!map) {
664 0 : return NT_STATUS_NO_MEMORY;
665 : }
666 :
667 1 : if (!pdb_getgrsid(map, *sid)) {
668 0 : status = NT_STATUS_NO_SUCH_ALIAS;
669 0 : goto done;
670 : }
671 :
672 1 : map->nt_name = talloc_strdup(map, info->acct_name);
673 1 : if (!map->nt_name) {
674 0 : status = NT_STATUS_NO_MEMORY;
675 0 : goto done;
676 : }
677 1 : map->comment = talloc_strdup(map, info->acct_desc);
678 1 : if (!map->comment) {
679 0 : status = NT_STATUS_NO_MEMORY;
680 0 : goto done;
681 : }
682 :
683 1 : status = pdb_update_group_mapping_entry(map);
684 :
685 1 : done:
686 1 : TALLOC_FREE(map);
687 1 : return status;
688 : }
689 :
690 92 : NTSTATUS pdb_default_add_aliasmem(struct pdb_methods *methods,
691 : const struct dom_sid *alias, const struct dom_sid *member)
692 : {
693 92 : if (!init_group_mapping()) {
694 0 : DEBUG(0,("failed to initialize group mapping\n"));
695 0 : return NT_STATUS_UNSUCCESSFUL;
696 : }
697 92 : return backend->add_aliasmem(alias, member);
698 : }
699 :
700 21 : NTSTATUS pdb_default_del_aliasmem(struct pdb_methods *methods,
701 : const struct dom_sid *alias, const struct dom_sid *member)
702 : {
703 21 : if (!init_group_mapping()) {
704 0 : DEBUG(0,("failed to initialize group mapping\n"));
705 0 : return NT_STATUS_UNSUCCESSFUL;
706 : }
707 21 : return backend->del_aliasmem(alias, member);
708 : }
709 :
710 42 : 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 42 : if (!init_group_mapping()) {
715 0 : DEBUG(0,("failed to initialize group mapping\n"));
716 0 : return NT_STATUS_UNSUCCESSFUL;
717 : }
718 42 : return backend->enum_aliasmem(alias, mem_ctx, pp_members,
719 : p_num_members);
720 : }
721 :
722 46778 : 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 46778 : if (!init_group_mapping()) {
735 0 : DEBUG(0,("failed to initialize group mapping\n"));
736 0 : return NT_STATUS_UNSUCCESSFUL;
737 : }
738 :
739 46778 : alias_sids = NULL;
740 46778 : num_alias_sids = 0;
741 :
742 46778 : result = alias_memberships(members, num_members,
743 : &alias_sids, &num_alias_sids);
744 :
745 46778 : if (!NT_STATUS_IS_OK(result))
746 0 : return result;
747 :
748 46778 : *p_num_alias_rids = 0;
749 :
750 46778 : if (num_alias_sids == 0) {
751 42708 : TALLOC_FREE(alias_sids);
752 42708 : return NT_STATUS_OK;
753 : }
754 :
755 4070 : *pp_alias_rids = talloc_array(mem_ctx, uint32_t, num_alias_sids);
756 4070 : if (*pp_alias_rids == NULL)
757 0 : return NT_STATUS_NO_MEMORY;
758 :
759 8956 : for (i=0; i<num_alias_sids; i++) {
760 4886 : if (!sid_peek_check_rid(domain_sid, &alias_sids[i],
761 4886 : &(*pp_alias_rids)[*p_num_alias_rids]))
762 2442 : continue;
763 2444 : *p_num_alias_rids += 1;
764 : }
765 :
766 4070 : TALLOC_FREE(alias_sids);
767 :
768 4070 : 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 181 : 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 181 : const char *name = NULL;
835 :
836 181 : DEBUG(10, ("Trying to create builtin alias %d\n", rid));
837 :
838 181 : 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 181 : map = talloc_zero(NULL, GROUP_MAP);
844 181 : if (!map) {
845 0 : return NT_STATUS_NO_MEMORY;
846 : }
847 :
848 181 : if (!lookup_sid(map, &sid, NULL, &name, &type)) {
849 0 : status = NT_STATUS_NO_SUCH_ALIAS;
850 0 : goto done;
851 : }
852 :
853 181 : if (gid == 0) {
854 181 : 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 49 : DEBUG(10, ("Creating alias %s with gid %u\n", name,
865 : (unsigned) gidformap));
866 :
867 49 : map->gid = gidformap;
868 49 : sid_copy(&map->sid, &sid);
869 49 : map->sid_name_use = SID_NAME_ALIAS;
870 49 : map->nt_name = talloc_strdup(map, name);
871 49 : if (!map->nt_name) {
872 0 : status = NT_STATUS_NO_MEMORY;
873 0 : goto done;
874 : }
875 49 : map->comment = talloc_strdup(map, "");
876 49 : if (!map->comment) {
877 0 : status = NT_STATUS_NO_MEMORY;
878 0 : goto done;
879 : }
880 :
881 49 : status = pdb_add_group_mapping_entry(map);
882 :
883 49 : 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 49 : done:
889 181 : TALLOC_FREE(map);
890 181 : return status;
891 : }
892 :
893 :
|