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.
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 2 of the License, or
12 * (at your option) any later version.
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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 static TDB_CONTEXT
*tdb
; /* used for driver files */
28 #define DATABASE_VERSION_V1 1 /* native byte format. */
29 #define DATABASE_VERSION_V2 2 /* le format. */
31 #define GROUP_PREFIX "UNIXGROUP/"
33 /* Alias memberships are stored reverse, as memberships. The performance
34 * critical operation is to determine the aliases a SID is member of, not
35 * listing alias members. So we store a list of alias SIDs a SID is member of
36 * hanging of the member as key.
38 #define MEMBEROF_PREFIX "MEMBEROF/"
41 static BOOL
enum_group_mapping(const DOM_SID
*sid
, enum SID_NAME_USE sid_name_use
, GROUP_MAP
**pp_rmap
,
42 size_t *p_num_entries
, BOOL unix_only
);
43 static BOOL
group_map_remove(const DOM_SID
*sid
);
45 /****************************************************************************
46 Open the group mapping tdb.
47 ****************************************************************************/
49 static BOOL
init_group_mapping(void)
51 const char *vstring
= "INFO/version";
53 GROUP_MAP
*map_table
= NULL
;
54 size_t num_entries
= 0;
59 tdb
= tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
61 DEBUG(0,("Failed to open group mapping database\n"));
65 /* handle a Samba upgrade */
66 tdb_lock_bystring(tdb
, vstring
);
68 /* Cope with byte-reversed older versions of the db. */
69 vers_id
= tdb_fetch_int32(tdb
, vstring
);
70 if ((vers_id
== DATABASE_VERSION_V1
) || (IREV(vers_id
) == DATABASE_VERSION_V1
)) {
71 /* Written on a bigendian machine with old fetch_int code. Save as le. */
72 tdb_store_int32(tdb
, vstring
, DATABASE_VERSION_V2
);
73 vers_id
= DATABASE_VERSION_V2
;
76 /* if its an unknown version we remove everthing in the db */
78 if (vers_id
!= DATABASE_VERSION_V2
) {
79 tdb_traverse(tdb
, tdb_traverse_delete_fn
, NULL
);
80 tdb_store_int32(tdb
, vstring
, DATABASE_VERSION_V2
);
83 tdb_unlock_bystring(tdb
, vstring
);
85 /* cleanup any map entries with a gid == -1 */
87 if ( enum_group_mapping( NULL
, SID_NAME_UNKNOWN
, &map_table
, &num_entries
, False
) ) {
90 for ( i
=0; i
<num_entries
; i
++ ) {
91 if ( map_table
[i
].gid
== -1 ) {
92 group_map_remove( &map_table
[i
].sid
);
96 SAFE_FREE( map_table
);
103 /****************************************************************************
104 ****************************************************************************/
105 static BOOL
add_mapping_entry(GROUP_MAP
*map
, int flag
)
109 fstring string_sid
="";
112 if(!init_group_mapping()) {
113 DEBUG(0,("failed to initialize group mapping\n"));
117 sid_to_string(string_sid
, &map
->sid
);
119 len
= tdb_pack(buf
, sizeof(buf
), "ddff",
120 map
->gid
, map
->sid_name_use
, map
->nt_name
, map
->comment
);
122 if (len
> sizeof(buf
))
125 slprintf(key
, sizeof(key
), "%s%s", GROUP_PREFIX
, string_sid
);
127 kbuf
.dsize
= strlen(key
)+1;
131 if (tdb_store(tdb
, kbuf
, dbuf
, flag
) != 0) return False
;
136 /****************************************************************************
137 initialise first time the mapping list
138 ****************************************************************************/
139 NTSTATUS
add_initial_entry(gid_t gid
, const char *sid
, enum SID_NAME_USE sid_name_use
, const char *nt_name
, const char *comment
)
143 if(!init_group_mapping()) {
144 DEBUG(0,("failed to initialize group mapping\n"));
145 return NT_STATUS_UNSUCCESSFUL
;
149 if (!string_to_sid(&map
.sid
, sid
)) {
150 DEBUG(0, ("string_to_sid failed: %s", sid
));
151 return NT_STATUS_UNSUCCESSFUL
;
154 map
.sid_name_use
=sid_name_use
;
155 fstrcpy(map
.nt_name
, nt_name
);
156 fstrcpy(map
.comment
, comment
);
158 return pdb_add_group_mapping_entry(&map
);
161 /****************************************************************************
162 Map a unix group to a newly created mapping
163 ****************************************************************************/
164 NTSTATUS
map_unix_group(const struct group
*grp
, GROUP_MAP
*pmap
)
168 const char *grpname
, *dom
, *name
;
171 if (pdb_getgrgid(&map
, grp
->gr_gid
)) {
172 return NT_STATUS_GROUP_EXISTS
;
175 map
.gid
= grp
->gr_gid
;
176 grpname
= grp
->gr_name
;
178 if (lookup_name(tmp_talloc_ctx(), grpname
, LOOKUP_NAME_ISOLATED
,
179 &dom
, &name
, NULL
, NULL
)) {
181 const char *tmp
= talloc_asprintf(
182 tmp_talloc_ctx(), "Unix Group %s", grp
->gr_name
);
184 DEBUG(5, ("%s exists as %s\\%s, retrying as \"%s\"\n",
185 grpname
, dom
, name
, tmp
));
189 if (lookup_name(tmp_talloc_ctx(), grpname
, LOOKUP_NAME_ISOLATED
,
190 NULL
, NULL
, NULL
, NULL
)) {
191 DEBUG(3, ("\"%s\" exists, can't map it\n", grp
->gr_name
));
192 return NT_STATUS_GROUP_EXISTS
;
195 fstrcpy(map
.nt_name
, grpname
);
197 if (pdb_rid_algorithm()) {
198 rid
= pdb_gid_to_group_rid( grp
->gr_gid
);
200 if (!pdb_new_rid(&rid
)) {
201 DEBUG(3, ("Could not get a new RID for %s\n",
203 return NT_STATUS_ACCESS_DENIED
;
207 sid_compose(&map
.sid
, get_global_sam_sid(), rid
);
208 map
.sid_name_use
= SID_NAME_DOM_GRP
;
209 fstrcpy(map
.comment
, talloc_asprintf(tmp_talloc_ctx(), "Unix Group %s",
212 status
= pdb_add_group_mapping_entry(&map
);
213 if (NT_STATUS_IS_OK(status
)) {
219 /****************************************************************************
220 Return the sid and the type of the unix group.
221 ****************************************************************************/
223 static BOOL
get_group_map_from_sid(DOM_SID sid
, GROUP_MAP
*map
)
230 if(!init_group_mapping()) {
231 DEBUG(0,("failed to initialize group mapping\n"));
235 /* the key is the SID, retrieving is direct */
237 sid_to_string(string_sid
, &sid
);
238 slprintf(key
, sizeof(key
), "%s%s", GROUP_PREFIX
, string_sid
);
241 kbuf
.dsize
= strlen(key
)+1;
243 dbuf
= tdb_fetch(tdb
, kbuf
);
247 ret
= tdb_unpack(dbuf
.dptr
, dbuf
.dsize
, "ddff",
248 &map
->gid
, &map
->sid_name_use
, &map
->nt_name
, &map
->comment
);
250 SAFE_FREE(dbuf
.dptr
);
253 DEBUG(3,("get_group_map_from_sid: tdb_unpack failure\n"));
257 sid_copy(&map
->sid
, &sid
);
262 /****************************************************************************
263 Return the sid and the type of the unix group.
264 ****************************************************************************/
266 static BOOL
get_group_map_from_gid(gid_t gid
, GROUP_MAP
*map
)
268 TDB_DATA kbuf
, dbuf
, newkey
;
272 if(!init_group_mapping()) {
273 DEBUG(0,("failed to initialize group mapping\n"));
277 /* we need to enumerate the TDB to find the GID */
279 for (kbuf
= tdb_firstkey(tdb
);
281 newkey
= tdb_nextkey(tdb
, kbuf
), safe_free(kbuf
.dptr
), kbuf
=newkey
) {
283 if (strncmp(kbuf
.dptr
, GROUP_PREFIX
, strlen(GROUP_PREFIX
)) != 0) continue;
285 dbuf
= tdb_fetch(tdb
, kbuf
);
289 fstrcpy(string_sid
, kbuf
.dptr
+strlen(GROUP_PREFIX
));
291 string_to_sid(&map
->sid
, string_sid
);
293 ret
= tdb_unpack(dbuf
.dptr
, dbuf
.dsize
, "ddff",
294 &map
->gid
, &map
->sid_name_use
, &map
->nt_name
, &map
->comment
);
296 SAFE_FREE(dbuf
.dptr
);
299 DEBUG(3,("get_group_map_from_gid: tdb_unpack failure\n"));
304 SAFE_FREE(kbuf
.dptr
);
312 /****************************************************************************
313 Return the sid and the type of the unix group.
314 ****************************************************************************/
316 static BOOL
get_group_map_from_ntname(const char *name
, GROUP_MAP
*map
)
318 TDB_DATA kbuf
, dbuf
, newkey
;
322 if(!init_group_mapping()) {
323 DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping\n"));
327 /* we need to enumerate the TDB to find the name */
329 for (kbuf
= tdb_firstkey(tdb
);
331 newkey
= tdb_nextkey(tdb
, kbuf
), safe_free(kbuf
.dptr
), kbuf
=newkey
) {
333 if (strncmp(kbuf
.dptr
, GROUP_PREFIX
, strlen(GROUP_PREFIX
)) != 0) continue;
335 dbuf
= tdb_fetch(tdb
, kbuf
);
339 fstrcpy(string_sid
, kbuf
.dptr
+strlen(GROUP_PREFIX
));
341 string_to_sid(&map
->sid
, string_sid
);
343 ret
= tdb_unpack(dbuf
.dptr
, dbuf
.dsize
, "ddff",
344 &map
->gid
, &map
->sid_name_use
, &map
->nt_name
, &map
->comment
);
346 SAFE_FREE(dbuf
.dptr
);
349 DEBUG(3,("get_group_map_from_ntname: tdb_unpack failure\n"));
353 if ( strequal(name
, map
->nt_name
) ) {
354 SAFE_FREE(kbuf
.dptr
);
362 /****************************************************************************
363 Remove a group mapping entry.
364 ****************************************************************************/
366 static BOOL
group_map_remove(const DOM_SID
*sid
)
372 if(!init_group_mapping()) {
373 DEBUG(0,("failed to initialize group mapping\n"));
377 /* the key is the SID, retrieving is direct */
379 sid_to_string(string_sid
, sid
);
380 slprintf(key
, sizeof(key
), "%s%s", GROUP_PREFIX
, string_sid
);
383 kbuf
.dsize
= strlen(key
)+1;
385 dbuf
= tdb_fetch(tdb
, kbuf
);
389 SAFE_FREE(dbuf
.dptr
);
391 if(tdb_delete(tdb
, kbuf
) != TDB_SUCCESS
)
397 /****************************************************************************
398 Enumerate the group mapping.
399 ****************************************************************************/
401 static BOOL
enum_group_mapping(const DOM_SID
*domsid
, enum SID_NAME_USE sid_name_use
, GROUP_MAP
**pp_rmap
,
402 size_t *p_num_entries
, BOOL unix_only
)
404 TDB_DATA kbuf
, dbuf
, newkey
;
413 if(!init_group_mapping()) {
414 DEBUG(0,("failed to initialize group mapping\n"));
421 for (kbuf
= tdb_firstkey(tdb
);
423 newkey
= tdb_nextkey(tdb
, kbuf
), safe_free(kbuf
.dptr
), kbuf
=newkey
) {
425 if (strncmp(kbuf
.dptr
, GROUP_PREFIX
, strlen(GROUP_PREFIX
)) != 0)
428 dbuf
= tdb_fetch(tdb
, kbuf
);
432 fstrcpy(string_sid
, kbuf
.dptr
+strlen(GROUP_PREFIX
));
434 ret
= tdb_unpack(dbuf
.dptr
, dbuf
.dsize
, "ddff",
435 &map
.gid
, &map
.sid_name_use
, &map
.nt_name
, &map
.comment
);
437 SAFE_FREE(dbuf
.dptr
);
440 DEBUG(3,("enum_group_mapping: tdb_unpack failure\n"));
444 /* list only the type or everything if UNKNOWN */
445 if (sid_name_use
!=SID_NAME_UNKNOWN
&& sid_name_use
!=map
.sid_name_use
) {
446 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map
.nt_name
));
450 if (unix_only
==ENUM_ONLY_MAPPED
&& map
.gid
==-1) {
451 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map
.nt_name
));
455 string_to_sid(&grpsid
, string_sid
);
456 sid_copy( &map
.sid
, &grpsid
);
458 sid_split_rid( &grpsid
, &rid
);
460 /* Only check the domain if we were given one */
462 if ( domsid
&& !sid_equal( domsid
, &grpsid
) ) {
463 DEBUG(11,("enum_group_mapping: group %s is not in domain %s\n",
464 string_sid
, sid_string_static(domsid
)));
468 DEBUG(11,("enum_group_mapping: returning group %s of "
469 "type %s\n", map
.nt_name
,
470 sid_type_lookup(map
.sid_name_use
)));
472 (*pp_rmap
) = SMB_REALLOC_ARRAY((*pp_rmap
), GROUP_MAP
, entries
+1);
474 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
480 mapt
[entries
].gid
= map
.gid
;
481 sid_copy( &mapt
[entries
].sid
, &map
.sid
);
482 mapt
[entries
].sid_name_use
= map
.sid_name_use
;
483 fstrcpy(mapt
[entries
].nt_name
, map
.nt_name
);
484 fstrcpy(mapt
[entries
].comment
, map
.comment
);
490 *p_num_entries
=entries
;
495 /* This operation happens on session setup, so it should better be fast. We
496 * store a list of aliases a SID is member of hanging off MEMBEROF/SID. */
498 static NTSTATUS
one_alias_membership(const DOM_SID
*member
,
499 DOM_SID
**sids
, size_t *num
)
501 fstring key
, string_sid
;
505 if (!init_group_mapping()) {
506 DEBUG(0,("failed to initialize group mapping\n"));
507 return NT_STATUS_ACCESS_DENIED
;
510 sid_to_string(string_sid
, member
);
511 slprintf(key
, sizeof(key
), "%s%s", MEMBEROF_PREFIX
, string_sid
);
513 kbuf
.dsize
= strlen(key
)+1;
516 dbuf
= tdb_fetch(tdb
, kbuf
);
518 if (dbuf
.dptr
== NULL
) {
524 while (next_token(&p
, string_sid
, " ", sizeof(string_sid
))) {
528 if (!string_to_sid(&alias
, string_sid
))
531 add_sid_to_array_unique(NULL
, &alias
, sids
, num
);
534 return NT_STATUS_NO_MEMORY
;
537 SAFE_FREE(dbuf
.dptr
);
541 static NTSTATUS
alias_memberships(const DOM_SID
*members
, size_t num_members
,
542 DOM_SID
**sids
, size_t *num
)
549 for (i
=0; i
<num_members
; i
++) {
550 NTSTATUS status
= one_alias_membership(&members
[i
], sids
, num
);
551 if (!NT_STATUS_IS_OK(status
))
557 static BOOL
is_aliasmem(const DOM_SID
*alias
, const DOM_SID
*member
)
562 /* This feels the wrong way round, but the on-disk data structure
563 * dictates it this way. */
564 if (!NT_STATUS_IS_OK(alias_memberships(member
, 1, &sids
, &num
)))
567 for (i
=0; i
<num
; i
++) {
568 if (sid_compare(alias
, &sids
[i
]) == 0) {
577 static NTSTATUS
add_aliasmem(const DOM_SID
*alias
, const DOM_SID
*member
)
583 char *new_memberstring
;
586 if(!init_group_mapping()) {
587 DEBUG(0,("failed to initialize group mapping\n"));
588 return NT_STATUS_ACCESS_DENIED
;
591 if (!get_group_map_from_sid(*alias
, &map
))
592 return NT_STATUS_NO_SUCH_ALIAS
;
594 if ( (map
.sid_name_use
!= SID_NAME_ALIAS
) &&
595 (map
.sid_name_use
!= SID_NAME_WKN_GRP
) )
596 return NT_STATUS_NO_SUCH_ALIAS
;
598 if (is_aliasmem(alias
, member
))
599 return NT_STATUS_MEMBER_IN_ALIAS
;
601 sid_to_string(string_sid
, member
);
602 slprintf(key
, sizeof(key
), "%s%s", MEMBEROF_PREFIX
, string_sid
);
604 kbuf
.dsize
= strlen(key
)+1;
607 dbuf
= tdb_fetch(tdb
, kbuf
);
609 sid_to_string(string_sid
, alias
);
611 if (dbuf
.dptr
!= NULL
) {
612 asprintf(&new_memberstring
, "%s %s", (char *)(dbuf
.dptr
),
615 new_memberstring
= SMB_STRDUP(string_sid
);
618 if (new_memberstring
== NULL
)
619 return NT_STATUS_NO_MEMORY
;
621 SAFE_FREE(dbuf
.dptr
);
622 dbuf
.dsize
= strlen(new_memberstring
)+1;
623 dbuf
.dptr
= new_memberstring
;
625 result
= tdb_store(tdb
, kbuf
, dbuf
, 0);
627 SAFE_FREE(new_memberstring
);
629 return (result
== 0 ? NT_STATUS_OK
: NT_STATUS_ACCESS_DENIED
);
632 struct aliasmem_closure
{
633 const DOM_SID
*alias
;
638 static int collect_aliasmem(TDB_CONTEXT
*tdb_ctx
, TDB_DATA key
, TDB_DATA data
,
641 struct aliasmem_closure
*closure
= (struct aliasmem_closure
*)state
;
643 fstring alias_string
;
645 if (strncmp(key
.dptr
, MEMBEROF_PREFIX
,
646 strlen(MEMBEROF_PREFIX
)) != 0)
651 while (next_token(&p
, alias_string
, " ", sizeof(alias_string
))) {
653 DOM_SID alias
, member
;
654 const char *member_string
;
657 if (!string_to_sid(&alias
, alias_string
))
660 if (sid_compare(closure
->alias
, &alias
) != 0)
663 /* Ok, we found the alias we're looking for in the membership
664 * list currently scanned. The key represents the alias
665 * member. Add that. */
667 member_string
= strchr(key
.dptr
, '/');
669 /* Above we tested for MEMBEROF_PREFIX which includes the
672 SMB_ASSERT(member_string
!= NULL
);
675 if (!string_to_sid(&member
, member_string
))
678 add_sid_to_array(NULL
, &member
, closure
->sids
, closure
->num
);
684 static NTSTATUS
enum_aliasmem(const DOM_SID
*alias
, DOM_SID
**sids
, size_t *num
)
687 struct aliasmem_closure closure
;
689 if(!init_group_mapping()) {
690 DEBUG(0,("failed to initialize group mapping\n"));
691 return NT_STATUS_ACCESS_DENIED
;
694 if (!get_group_map_from_sid(*alias
, &map
))
695 return NT_STATUS_NO_SUCH_ALIAS
;
697 if ( (map
.sid_name_use
!= SID_NAME_ALIAS
) &&
698 (map
.sid_name_use
!= SID_NAME_WKN_GRP
) )
699 return NT_STATUS_NO_SUCH_ALIAS
;
704 closure
.alias
= alias
;
708 tdb_traverse(tdb
, collect_aliasmem
, &closure
);
712 static NTSTATUS
del_aliasmem(const DOM_SID
*alias
, const DOM_SID
*member
)
723 result
= alias_memberships(member
, 1, &sids
, &num
);
725 if (!NT_STATUS_IS_OK(result
))
728 for (i
=0; i
<num
; i
++) {
729 if (sid_compare(&sids
[i
], alias
) == 0) {
737 return NT_STATUS_MEMBER_NOT_IN_ALIAS
;
741 sids
[i
] = sids
[num
-1];
745 sid_to_string(sid_string
, member
);
746 slprintf(key
, sizeof(key
), "%s%s", MEMBEROF_PREFIX
, sid_string
);
748 kbuf
.dsize
= strlen(key
)+1;
752 return tdb_delete(tdb
, kbuf
) == 0 ?
753 NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
755 member_string
= SMB_STRDUP("");
757 if (member_string
== NULL
) {
759 return NT_STATUS_NO_MEMORY
;
762 for (i
=0; i
<num
; i
++) {
763 char *s
= member_string
;
765 sid_to_string(sid_string
, &sids
[i
]);
766 asprintf(&member_string
, "%s %s", s
, sid_string
);
769 if (member_string
== NULL
) {
771 return NT_STATUS_NO_MEMORY
;
775 dbuf
.dsize
= strlen(member_string
)+1;
776 dbuf
.dptr
= member_string
;
778 result
= tdb_store(tdb
, kbuf
, dbuf
, 0) == 0 ?
779 NT_STATUS_OK
: NT_STATUS_ACCESS_DENIED
;
782 SAFE_FREE(member_string
);
789 * High level functions
790 * better to use them than the lower ones.
792 * we are checking if the group is in the mapping file
793 * and if the group is an existing unix group
797 /* get a domain group from it's SID */
799 BOOL
get_domain_group_from_sid(DOM_SID sid
, GROUP_MAP
*map
)
804 if(!init_group_mapping()) {
805 DEBUG(0,("failed to initialize group mapping\n"));
809 DEBUG(10, ("get_domain_group_from_sid\n"));
811 /* if the group is NOT in the database, it CAN NOT be a domain group */
814 ret
= pdb_getgrsid(map
, sid
);
817 /* special case check for rid 513 */
822 sid_peek_rid( &sid
, &rid
);
824 if ( rid
== DOMAIN_GROUP_RID_USERS
) {
825 fstrcpy( map
->nt_name
, "None" );
826 fstrcpy( map
->comment
, "Ordinary Users" );
827 sid_copy( &map
->sid
, &sid
);
828 map
->sid_name_use
= SID_NAME_DOM_GRP
;
836 DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n"));
838 /* if it's not a domain group, continue */
839 if (map
->sid_name_use
!=SID_NAME_DOM_GRP
) {
843 DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n"));
849 DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n",(unsigned long)map
->gid
));
851 grp
= getgrgid(map
->gid
);
853 DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n"));
857 DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX security\n"));
862 /****************************************************************************
863 Create a UNIX group on demand.
864 ****************************************************************************/
866 int smb_create_group(const char *unix_group
, gid_t
*new_gid
)
874 /* defer to scripts */
876 if ( *lp_addgroup_script() ) {
877 pstrcpy(add_script
, lp_addgroup_script());
878 pstring_sub(add_script
, "%g", unix_group
);
879 ret
= smbrun(add_script
, &fd
);
880 DEBUG(ret
? 0 : 3,("smb_create_group: Running the command `%s' gave %d\n",add_script
,ret
));
888 if (read(fd
, output
, sizeof(output
)) > 0) {
889 *new_gid
= (gid_t
)strtoul(output
, NULL
, 10);
898 struct group
*grp
= getgrnam(unix_group
);
901 *new_gid
= grp
->gr_gid
;
907 /****************************************************************************
908 Delete a UNIX group on demand.
909 ****************************************************************************/
911 int smb_delete_group(const char *unix_group
)
916 /* defer to scripts */
918 if ( *lp_delgroup_script() ) {
919 pstrcpy(del_script
, lp_delgroup_script());
920 pstring_sub(del_script
, "%g", unix_group
);
921 ret
= smbrun(del_script
,NULL
);
922 DEBUG(ret
? 0 : 3,("smb_delete_group: Running the command `%s' gave %d\n",del_script
,ret
));
929 /****************************************************************************
930 Set a user's primary UNIX group.
931 ****************************************************************************/
932 int smb_set_primary_group(const char *unix_group
, const char* unix_user
)
937 /* defer to scripts */
939 if ( *lp_setprimarygroup_script() ) {
940 pstrcpy(add_script
, lp_setprimarygroup_script());
941 all_string_sub(add_script
, "%g", unix_group
, sizeof(add_script
));
942 all_string_sub(add_script
, "%u", unix_user
, sizeof(add_script
));
943 ret
= smbrun(add_script
,NULL
);
945 DEBUG(ret
? 0 : 3,("smb_set_primary_group: "
946 "Running the command `%s' gave %d\n",add_script
,ret
));
953 /****************************************************************************
954 Add a user to a UNIX group.
955 ****************************************************************************/
957 int smb_add_user_group(const char *unix_group
, const char *unix_user
)
962 /* defer to scripts */
964 if ( *lp_addusertogroup_script() ) {
965 pstrcpy(add_script
, lp_addusertogroup_script());
966 pstring_sub(add_script
, "%g", unix_group
);
967 pstring_sub(add_script
, "%u", unix_user
);
968 ret
= smbrun(add_script
,NULL
);
969 DEBUG(ret
? 0 : 3,("smb_add_user_group: Running the command `%s' gave %d\n",add_script
,ret
));
976 /****************************************************************************
977 Delete a user from a UNIX group
978 ****************************************************************************/
980 int smb_delete_user_group(const char *unix_group
, const char *unix_user
)
985 /* defer to scripts */
987 if ( *lp_deluserfromgroup_script() ) {
988 pstrcpy(del_script
, lp_deluserfromgroup_script());
989 pstring_sub(del_script
, "%g", unix_group
);
990 pstring_sub(del_script
, "%u", unix_user
);
991 ret
= smbrun(del_script
,NULL
);
992 DEBUG(ret
? 0 : 3,("smb_delete_user_group: Running the command `%s' gave %d\n",del_script
,ret
));
1000 NTSTATUS
pdb_default_getgrsid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1003 return get_group_map_from_sid(sid
, map
) ?
1004 NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1007 NTSTATUS
pdb_default_getgrgid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1010 return get_group_map_from_gid(gid
, map
) ?
1011 NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1014 NTSTATUS
pdb_default_getgrnam(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1017 return get_group_map_from_ntname(name
, map
) ?
1018 NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1021 NTSTATUS
pdb_default_add_group_mapping_entry(struct pdb_methods
*methods
,
1024 return add_mapping_entry(map
, TDB_INSERT
) ?
1025 NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1028 NTSTATUS
pdb_default_update_group_mapping_entry(struct pdb_methods
*methods
,
1031 return add_mapping_entry(map
, TDB_REPLACE
) ?
1032 NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1035 NTSTATUS
pdb_default_delete_group_mapping_entry(struct pdb_methods
*methods
,
1038 return group_map_remove(&sid
) ?
1039 NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1042 NTSTATUS
pdb_default_enum_group_mapping(struct pdb_methods
*methods
,
1043 const DOM_SID
*sid
, enum SID_NAME_USE sid_name_use
,
1044 GROUP_MAP
**pp_rmap
, size_t *p_num_entries
,
1047 return enum_group_mapping(sid
, sid_name_use
, pp_rmap
, p_num_entries
, unix_only
) ?
1048 NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
1051 NTSTATUS
pdb_default_find_alias(struct pdb_methods
*methods
,
1052 const char *name
, DOM_SID
*sid
)
1056 if (!pdb_getgrnam(&map
, name
))
1057 return NT_STATUS_NO_SUCH_ALIAS
;
1059 if ((map
.sid_name_use
!= SID_NAME_WKN_GRP
) &&
1060 (map
.sid_name_use
!= SID_NAME_ALIAS
))
1061 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
1063 sid_copy(sid
, &map
.sid
);
1064 return NT_STATUS_OK
;
1067 NTSTATUS
pdb_default_create_alias(struct pdb_methods
*methods
,
1068 const char *name
, uint32
*rid
)
1071 enum SID_NAME_USE type
;
1076 TALLOC_CTX
*mem_ctx
;
1079 DEBUG(10, ("Trying to create alias %s\n", name
));
1081 mem_ctx
= talloc_new(NULL
);
1082 if (mem_ctx
== NULL
) {
1083 return NT_STATUS_NO_MEMORY
;
1086 exists
= lookup_name(mem_ctx
, name
, LOOKUP_NAME_ISOLATED
,
1087 NULL
, NULL
, &sid
, &type
);
1088 TALLOC_FREE(mem_ctx
);
1091 return NT_STATUS_ALIAS_EXISTS
;
1094 if (!winbind_allocate_gid(&gid
)) {
1095 DEBUG(3, ("Could not get a gid out of winbind\n"));
1096 return NT_STATUS_ACCESS_DENIED
;
1099 if (!pdb_new_rid(&new_rid
)) {
1100 DEBUG(0, ("Could not allocate a RID -- wasted a gid :-(\n"));
1101 return NT_STATUS_ACCESS_DENIED
;
1104 DEBUG(10, ("Creating alias %s with gid %d and rid %d\n",
1105 name
, gid
, new_rid
));
1107 sid_copy(&sid
, get_global_sam_sid());
1108 sid_append_rid(&sid
, new_rid
);
1111 sid_copy(&map
.sid
, &sid
);
1112 map
.sid_name_use
= SID_NAME_ALIAS
;
1113 fstrcpy(map
.nt_name
, name
);
1114 fstrcpy(map
.comment
, "");
1116 status
= pdb_add_group_mapping_entry(&map
);
1118 if (!NT_STATUS_IS_OK(status
)) {
1119 DEBUG(0, ("Could not add group mapping entry for alias %s "
1120 "(%s)\n", name
, nt_errstr(status
)));
1126 return NT_STATUS_OK
;
1129 NTSTATUS
pdb_default_delete_alias(struct pdb_methods
*methods
,
1132 return pdb_delete_group_mapping_entry(*sid
);
1135 NTSTATUS
pdb_default_get_aliasinfo(struct pdb_methods
*methods
,
1137 struct acct_info
*info
)
1141 if (!pdb_getgrsid(&map
, *sid
))
1142 return NT_STATUS_NO_SUCH_ALIAS
;
1144 if ((map
.sid_name_use
!= SID_NAME_ALIAS
) &&
1145 (map
.sid_name_use
!= SID_NAME_WKN_GRP
)) {
1146 DEBUG(2, ("%s is a %s, expected an alias\n",
1147 sid_string_static(sid
),
1148 sid_type_lookup(map
.sid_name_use
)));
1149 return NT_STATUS_NO_SUCH_ALIAS
;
1152 fstrcpy(info
->acct_name
, map
.nt_name
);
1153 fstrcpy(info
->acct_desc
, map
.comment
);
1154 sid_peek_rid(&map
.sid
, &info
->rid
);
1155 return NT_STATUS_OK
;
1158 NTSTATUS
pdb_default_set_aliasinfo(struct pdb_methods
*methods
,
1160 struct acct_info
*info
)
1164 if (!pdb_getgrsid(&map
, *sid
))
1165 return NT_STATUS_NO_SUCH_ALIAS
;
1167 fstrcpy(map
.nt_name
, info
->acct_name
);
1168 fstrcpy(map
.comment
, info
->acct_desc
);
1170 return pdb_update_group_mapping_entry(&map
);
1173 NTSTATUS
pdb_default_add_aliasmem(struct pdb_methods
*methods
,
1174 const DOM_SID
*alias
, const DOM_SID
*member
)
1176 return add_aliasmem(alias
, member
);
1179 NTSTATUS
pdb_default_del_aliasmem(struct pdb_methods
*methods
,
1180 const DOM_SID
*alias
, const DOM_SID
*member
)
1182 return del_aliasmem(alias
, member
);
1185 NTSTATUS
pdb_default_enum_aliasmem(struct pdb_methods
*methods
,
1186 const DOM_SID
*alias
, DOM_SID
**pp_members
,
1187 size_t *p_num_members
)
1189 return enum_aliasmem(alias
, pp_members
, p_num_members
);
1192 NTSTATUS
pdb_default_alias_memberships(struct pdb_methods
*methods
,
1193 TALLOC_CTX
*mem_ctx
,
1194 const DOM_SID
*domain_sid
,
1195 const DOM_SID
*members
,
1197 uint32
**pp_alias_rids
,
1198 size_t *p_num_alias_rids
)
1200 DOM_SID
*alias_sids
;
1201 size_t i
, num_alias_sids
;
1207 result
= alias_memberships(members
, num_members
,
1208 &alias_sids
, &num_alias_sids
);
1210 if (!NT_STATUS_IS_OK(result
))
1213 *pp_alias_rids
= TALLOC_ARRAY(mem_ctx
, uint32
, num_alias_sids
);
1214 if (*pp_alias_rids
== NULL
)
1215 return NT_STATUS_NO_MEMORY
;
1217 *p_num_alias_rids
= 0;
1219 for (i
=0; i
<num_alias_sids
; i
++) {
1220 if (!sid_peek_check_rid(domain_sid
, &alias_sids
[i
],
1221 &(*pp_alias_rids
)[*p_num_alias_rids
]))
1223 *p_num_alias_rids
+= 1;
1226 SAFE_FREE(alias_sids
);
1228 return NT_STATUS_OK
;
1231 /**********************************************************************
1232 no ops for passdb backends that don't implement group mapping
1233 *********************************************************************/
1235 NTSTATUS
pdb_nop_getgrsid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1238 return NT_STATUS_UNSUCCESSFUL
;
1241 NTSTATUS
pdb_nop_getgrgid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1244 return NT_STATUS_UNSUCCESSFUL
;
1247 NTSTATUS
pdb_nop_getgrnam(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1250 return NT_STATUS_UNSUCCESSFUL
;
1253 NTSTATUS
pdb_nop_add_group_mapping_entry(struct pdb_methods
*methods
,
1256 return NT_STATUS_UNSUCCESSFUL
;
1259 NTSTATUS
pdb_nop_update_group_mapping_entry(struct pdb_methods
*methods
,
1262 return NT_STATUS_UNSUCCESSFUL
;
1265 NTSTATUS
pdb_nop_delete_group_mapping_entry(struct pdb_methods
*methods
,
1268 return NT_STATUS_UNSUCCESSFUL
;
1271 NTSTATUS
pdb_nop_enum_group_mapping(struct pdb_methods
*methods
,
1272 enum SID_NAME_USE sid_name_use
,
1273 GROUP_MAP
**rmap
, size_t *num_entries
,
1276 return NT_STATUS_UNSUCCESSFUL
;
1279 /****************************************************************************
1280 These need to be redirected through pdb_interface.c
1281 ****************************************************************************/
1282 BOOL
pdb_get_dom_grp_info(const DOM_SID
*sid
, struct acct_info
*info
)
1288 res
= get_domain_group_from_sid(*sid
, &map
);
1294 fstrcpy(info
->acct_name
, map
.nt_name
);
1295 fstrcpy(info
->acct_desc
, map
.comment
);
1296 sid_peek_rid(sid
, &info
->rid
);
1300 BOOL
pdb_set_dom_grp_info(const DOM_SID
*sid
, const struct acct_info
*info
)
1304 if (!get_domain_group_from_sid(*sid
, &map
))
1307 fstrcpy(map
.nt_name
, info
->acct_name
);
1308 fstrcpy(map
.comment
, info
->acct_desc
);
1310 return NT_STATUS_IS_OK(pdb_update_group_mapping_entry(&map
));
1313 /********************************************************************
1314 Really just intended to be called by smbd
1315 ********************************************************************/
1317 NTSTATUS
pdb_create_builtin_alias(uint32 rid
)
1320 enum SID_NAME_USE type
;
1323 TALLOC_CTX
*mem_ctx
;
1325 const char *name
= NULL
;
1328 DEBUG(10, ("Trying to create builtin alias %d\n", rid
));
1330 if ( !sid_compose( &sid
, &global_sid_Builtin
, rid
) ) {
1331 return NT_STATUS_NO_SUCH_ALIAS
;
1334 if ( (mem_ctx
= talloc_new(NULL
)) == NULL
) {
1335 return NT_STATUS_NO_MEMORY
;
1338 if ( !lookup_sid(mem_ctx
, &sid
, NULL
, &name
, &type
) ) {
1339 TALLOC_FREE( mem_ctx
);
1340 return NT_STATUS_NO_SUCH_ALIAS
;
1343 /* validate RID so copy the name and move on */
1345 fstrcpy( groupname
, name
);
1346 TALLOC_FREE( mem_ctx
);
1348 if (!winbind_allocate_gid(&gid
)) {
1349 DEBUG(3, ("pdb_create_builtin_alias: Could not get a gid out of winbind\n"));
1350 return NT_STATUS_ACCESS_DENIED
;
1353 DEBUG(10,("Creating alias %s with gid %d\n", name
, gid
));
1356 sid_copy(&map
.sid
, &sid
);
1357 map
.sid_name_use
= SID_NAME_ALIAS
;
1358 fstrcpy(map
.nt_name
, name
);
1359 fstrcpy(map
.comment
, "");
1361 status
= pdb_add_group_mapping_entry(&map
);
1363 if (!NT_STATUS_IS_OK(status
)) {
1364 DEBUG(0, ("pdb_create_builtin_alias: Could not add group mapping entry for alias %d "
1365 "(%s)\n", rid
, nt_errstr(status
)));