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