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