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.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern DOM_SID global_sid_Builtin;
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/"
40 /****************************************************************************
41 dump the mapping group mapping to a text file
42 ****************************************************************************/
43 char *decode_sid_name_use(fstring group, enum SID_NAME_USE name_use)
45 static fstring group_type;
49 fstrcpy(group_type,"User");
51 case SID_NAME_DOM_GRP:
52 fstrcpy(group_type,"Domain group");
55 fstrcpy(group_type,"Domain");
58 fstrcpy(group_type,"Local group");
60 case SID_NAME_WKN_GRP:
61 fstrcpy(group_type,"Builtin group");
63 case SID_NAME_DELETED:
64 fstrcpy(group_type,"Deleted");
66 case SID_NAME_INVALID:
67 fstrcpy(group_type,"Invalid");
69 case SID_NAME_UNKNOWN:
71 fstrcpy(group_type,"Unknown type");
75 fstrcpy(group, group_type);
79 /****************************************************************************
80 initialise first time the mapping list - called from init_group_mapping()
81 ****************************************************************************/
82 static BOOL default_group_mapping(void)
91 /* Add the Wellknown groups */
93 add_initial_entry(-1, "S-1-5-32-544", SID_NAME_WKN_GRP, "Administrators", "");
94 add_initial_entry(-1, "S-1-5-32-545", SID_NAME_WKN_GRP, "Users", "");
95 add_initial_entry(-1, "S-1-5-32-546", SID_NAME_WKN_GRP, "Guests", "");
96 add_initial_entry(-1, "S-1-5-32-547", SID_NAME_WKN_GRP, "Power Users", "");
97 add_initial_entry(-1, "S-1-5-32-548", SID_NAME_WKN_GRP, "Account Operators", "");
98 add_initial_entry(-1, "S-1-5-32-549", SID_NAME_WKN_GRP, "System Operators", "");
99 add_initial_entry(-1, "S-1-5-32-550", SID_NAME_WKN_GRP, "Print Operators", "");
100 add_initial_entry(-1, "S-1-5-32-551", SID_NAME_WKN_GRP, "Backup Operators", "");
101 add_initial_entry(-1, "S-1-5-32-552", SID_NAME_WKN_GRP, "Replicators", "");
103 /* Add the defaults domain groups */
105 sid_copy(&sid_admins, get_global_sam_sid());
106 sid_append_rid(&sid_admins, DOMAIN_GROUP_RID_ADMINS);
107 sid_to_string(str_admins, &sid_admins);
108 add_initial_entry(-1, str_admins, SID_NAME_DOM_GRP, "Domain Admins", "");
110 sid_copy(&sid_users, get_global_sam_sid());
111 sid_append_rid(&sid_users, DOMAIN_GROUP_RID_USERS);
112 sid_to_string(str_users, &sid_users);
113 add_initial_entry(-1, str_users, SID_NAME_DOM_GRP, "Domain Users", "");
115 sid_copy(&sid_guests, get_global_sam_sid());
116 sid_append_rid(&sid_guests, DOMAIN_GROUP_RID_GUESTS);
117 sid_to_string(str_guests, &sid_guests);
118 add_initial_entry(-1, str_guests, SID_NAME_DOM_GRP, "Domain Guests", "");
123 /****************************************************************************
124 Open the group mapping tdb.
125 ****************************************************************************/
127 static BOOL init_group_mapping(void)
129 const char *vstring = "INFO/version";
134 tdb = tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
136 DEBUG(0,("Failed to open group mapping database\n"));
140 /* handle a Samba upgrade */
141 tdb_lock_bystring(tdb, vstring, 0);
143 /* Cope with byte-reversed older versions of the db. */
144 vers_id = tdb_fetch_int32(tdb, vstring);
145 if ((vers_id == DATABASE_VERSION_V1) || (IREV(vers_id) == DATABASE_VERSION_V1)) {
146 /* Written on a bigendian machine with old fetch_int code. Save as le. */
147 tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
148 vers_id = DATABASE_VERSION_V2;
151 if (vers_id != DATABASE_VERSION_V2) {
152 tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
153 tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
156 tdb_unlock_bystring(tdb, vstring);
158 /* write a list of default groups */
159 if(!default_group_mapping())
165 /****************************************************************************
166 ****************************************************************************/
167 static BOOL add_mapping_entry(GROUP_MAP *map, int flag)
171 fstring string_sid="";
174 if(!init_group_mapping()) {
175 DEBUG(0,("failed to initialize group mapping\n"));
179 sid_to_string(string_sid, &map->sid);
181 len = tdb_pack(buf, sizeof(buf), "ddff",
182 map->gid, map->sid_name_use, map->nt_name, map->comment);
184 if (len > sizeof(buf))
187 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
189 kbuf.dsize = strlen(key)+1;
193 if (tdb_store(tdb, kbuf, dbuf, flag) != 0) return False;
198 /****************************************************************************
199 initialise first time the mapping list
200 ****************************************************************************/
201 BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_use, const char *nt_name, const char *comment)
205 if(!init_group_mapping()) {
206 DEBUG(0,("failed to initialize group mapping\n"));
211 if (!string_to_sid(&map.sid, sid)) {
212 DEBUG(0, ("string_to_sid failed: %s", sid));
216 map.sid_name_use=sid_name_use;
217 fstrcpy(map.nt_name, nt_name);
218 fstrcpy(map.comment, comment);
220 return pdb_add_group_mapping_entry(&map);
223 /****************************************************************************
224 Return the sid and the type of the unix group.
225 ****************************************************************************/
227 static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map)
234 if(!init_group_mapping()) {
235 DEBUG(0,("failed to initialize group mapping\n"));
239 /* the key is the SID, retrieving is direct */
241 sid_to_string(string_sid, &sid);
242 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
245 kbuf.dsize = strlen(key)+1;
247 dbuf = tdb_fetch(tdb, kbuf);
251 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
252 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
254 SAFE_FREE(dbuf.dptr);
257 DEBUG(3,("get_group_map_from_sid: tdb_unpack failure\n"));
261 sid_copy(&map->sid, &sid);
266 /****************************************************************************
267 Return the sid and the type of the unix group.
268 ****************************************************************************/
270 static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map)
272 TDB_DATA kbuf, dbuf, newkey;
276 if(!init_group_mapping()) {
277 DEBUG(0,("failed to initialize group mapping\n"));
281 /* we need to enumerate the TDB to find the GID */
283 for (kbuf = tdb_firstkey(tdb);
285 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
287 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue;
289 dbuf = tdb_fetch(tdb, kbuf);
293 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
295 string_to_sid(&map->sid, string_sid);
297 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
298 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
300 SAFE_FREE(dbuf.dptr);
303 DEBUG(3,("get_group_map_from_gid: tdb_unpack failure\n"));
308 SAFE_FREE(kbuf.dptr);
316 /****************************************************************************
317 Return the sid and the type of the unix group.
318 ****************************************************************************/
320 static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map)
322 TDB_DATA kbuf, dbuf, newkey;
326 if(!init_group_mapping()) {
327 DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping\n"));
331 /* we need to enumerate the TDB to find the name */
333 for (kbuf = tdb_firstkey(tdb);
335 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
337 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue;
339 dbuf = tdb_fetch(tdb, kbuf);
343 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
345 string_to_sid(&map->sid, string_sid);
347 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
348 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
350 SAFE_FREE(dbuf.dptr);
353 DEBUG(3,("get_group_map_from_ntname: tdb_unpack failure\n"));
357 if (StrCaseCmp(name, map->nt_name)==0) {
358 SAFE_FREE(kbuf.dptr);
366 /****************************************************************************
367 Remove a group mapping entry.
368 ****************************************************************************/
370 static BOOL group_map_remove(DOM_SID sid)
376 if(!init_group_mapping()) {
377 DEBUG(0,("failed to initialize group mapping\n"));
381 /* the key is the SID, retrieving is direct */
383 sid_to_string(string_sid, &sid);
384 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
387 kbuf.dsize = strlen(key)+1;
389 dbuf = tdb_fetch(tdb, kbuf);
393 SAFE_FREE(dbuf.dptr);
395 if(tdb_delete(tdb, kbuf) != TDB_SUCCESS)
401 /****************************************************************************
402 Enumerate the group mapping.
403 ****************************************************************************/
405 static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
406 int *num_entries, BOOL unix_only)
408 TDB_DATA kbuf, dbuf, newkey;
416 if(!init_group_mapping()) {
417 DEBUG(0,("failed to initialize group mapping\n"));
424 for (kbuf = tdb_firstkey(tdb);
426 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
428 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0)
431 dbuf = tdb_fetch(tdb, kbuf);
435 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
437 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
438 &map.gid, &map.sid_name_use, &map.nt_name, &map.comment);
440 SAFE_FREE(dbuf.dptr);
443 DEBUG(3,("enum_group_mapping: tdb_unpack failure\n"));
447 /* list only the type or everything if UNKNOWN */
448 if (sid_name_use!=SID_NAME_UNKNOWN && sid_name_use!=map.sid_name_use) {
449 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
453 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
454 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
458 string_to_sid(&map.sid, string_sid);
460 decode_sid_name_use(group_type, map.sid_name_use);
461 DEBUG(11,("enum_group_mapping: returning group %s of type %s\n", map.nt_name ,group_type));
463 mapt= SMB_REALLOC_ARRAY((*rmap), GROUP_MAP, entries+1);
465 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
472 mapt[entries].gid = map.gid;
473 sid_copy( &mapt[entries].sid, &map.sid);
474 mapt[entries].sid_name_use = map.sid_name_use;
475 fstrcpy(mapt[entries].nt_name, map.nt_name);
476 fstrcpy(mapt[entries].comment, map.comment);
482 *num_entries=entries;
487 /* This operation happens on session setup, so it should better be fast. We
488 * store a list of aliases a SID is member of hanging off MEMBEROF/SID. */
490 static NTSTATUS one_alias_membership(const DOM_SID *member,
491 DOM_SID **sids, int *num)
493 fstring key, string_sid;
497 if (!init_group_mapping()) {
498 DEBUG(0,("failed to initialize group mapping\n"));
499 return NT_STATUS_ACCESS_DENIED;
502 sid_to_string(string_sid, member);
503 slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid);
505 kbuf.dsize = strlen(key)+1;
508 dbuf = tdb_fetch(tdb, kbuf);
510 if (dbuf.dptr == NULL) {
516 while (next_token(&p, string_sid, " ", sizeof(string_sid))) {
520 if (!string_to_sid(&alias, string_sid))
523 add_sid_to_array_unique(NULL, &alias, sids, num);
526 return NT_STATUS_NO_MEMORY;
529 SAFE_FREE(dbuf.dptr);
533 static NTSTATUS alias_memberships(const DOM_SID *members, int num_members,
534 DOM_SID **sids, int *num)
541 for (i=0; i<num_members; i++) {
542 NTSTATUS status = one_alias_membership(&members[i], sids, num);
543 if (!NT_STATUS_IS_OK(status))
549 static BOOL is_aliasmem(const DOM_SID *alias, const DOM_SID *member)
554 /* This feels the wrong way round, but the on-disk data structure
555 * dictates it this way. */
556 if (!NT_STATUS_IS_OK(alias_memberships(member, 1, &sids, &num)))
559 for (i=0; i<num; i++) {
560 if (sid_compare(alias, &sids[i]) == 0) {
569 static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
575 char *new_memberstring;
578 if(!init_group_mapping()) {
579 DEBUG(0,("failed to initialize group mapping\n"));
580 return NT_STATUS_ACCESS_DENIED;
583 if (!get_group_map_from_sid(*alias, &map))
584 return NT_STATUS_NO_SUCH_ALIAS;
586 if ( (map.sid_name_use != SID_NAME_ALIAS) &&
587 (map.sid_name_use != SID_NAME_WKN_GRP) )
588 return NT_STATUS_NO_SUCH_ALIAS;
590 if (is_aliasmem(alias, member))
591 return NT_STATUS_MEMBER_IN_ALIAS;
593 sid_to_string(string_sid, member);
594 slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid);
596 kbuf.dsize = strlen(key)+1;
599 dbuf = tdb_fetch(tdb, kbuf);
601 sid_to_string(string_sid, alias);
603 if (dbuf.dptr != NULL) {
604 asprintf(&new_memberstring, "%s %s", (char *)(dbuf.dptr),
607 new_memberstring = SMB_STRDUP(string_sid);
610 if (new_memberstring == NULL)
611 return NT_STATUS_NO_MEMORY;
613 SAFE_FREE(dbuf.dptr);
614 dbuf.dsize = strlen(new_memberstring)+1;
615 dbuf.dptr = new_memberstring;
617 result = tdb_store(tdb, kbuf, dbuf, 0);
619 SAFE_FREE(new_memberstring);
621 return (result == 0 ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED);
624 struct aliasmem_closure {
625 const DOM_SID *alias;
630 static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data,
633 struct aliasmem_closure *closure = (struct aliasmem_closure *)state;
635 fstring alias_string;
637 if (strncmp(key.dptr, MEMBEROF_PREFIX,
638 strlen(MEMBEROF_PREFIX)) != 0)
643 while (next_token(&p, alias_string, " ", sizeof(alias_string))) {
645 DOM_SID alias, member;
646 const char *member_string;
649 if (!string_to_sid(&alias, alias_string))
652 if (sid_compare(closure->alias, &alias) != 0)
655 /* Ok, we found the alias we're looking for in the membership
656 * list currently scanned. The key represents the alias
657 * member. Add that. */
659 member_string = strchr(key.dptr, '/');
661 /* Above we tested for MEMBEROF_PREFIX which includes the
664 SMB_ASSERT(member_string != NULL);
667 if (!string_to_sid(&member, member_string))
670 add_sid_to_array(NULL, &member, closure->sids, closure->num);
676 static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num)
679 struct aliasmem_closure closure;
681 if(!init_group_mapping()) {
682 DEBUG(0,("failed to initialize group mapping\n"));
683 return NT_STATUS_ACCESS_DENIED;
686 if (!get_group_map_from_sid(*alias, &map))
687 return NT_STATUS_NO_SUCH_ALIAS;
689 if ( (map.sid_name_use != SID_NAME_ALIAS) &&
690 (map.sid_name_use != SID_NAME_WKN_GRP) )
691 return NT_STATUS_NO_SUCH_ALIAS;
696 closure.alias = alias;
700 tdb_traverse(tdb, collect_aliasmem, &closure);
704 static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
715 result = alias_memberships(member, 1, &sids, &num);
717 if (!NT_STATUS_IS_OK(result))
720 for (i=0; i<num; i++) {
721 if (sid_compare(&sids[i], alias) == 0) {
729 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
733 sids[i] = sids[num-1];
737 sid_to_string(sid_string, member);
738 slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, sid_string);
740 kbuf.dsize = strlen(key)+1;
744 return tdb_delete(tdb, kbuf) == 0 ?
745 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
747 member_string = SMB_STRDUP("");
749 if (member_string == NULL) {
751 return NT_STATUS_NO_MEMORY;
754 for (i=0; i<num; i++) {
755 char *s = member_string;
757 sid_to_string(sid_string, &sids[i]);
758 asprintf(&member_string, "%s %s", s, sid_string);
761 if (member_string == NULL) {
763 return NT_STATUS_NO_MEMORY;
767 dbuf.dsize = strlen(member_string)+1;
768 dbuf.dptr = member_string;
770 result = tdb_store(tdb, kbuf, dbuf, 0) == 0 ?
771 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
774 SAFE_FREE(member_string);
781 * High level functions
782 * better to use them than the lower ones.
784 * we are checking if the group is in the mapping file
785 * and if the group is an existing unix group
789 /* get a domain group from it's SID */
791 BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map)
796 if(!init_group_mapping()) {
797 DEBUG(0,("failed to initialize group mapping\n"));
801 DEBUG(10, ("get_domain_group_from_sid\n"));
803 /* if the group is NOT in the database, it CAN NOT be a domain group */
806 ret = pdb_getgrsid(map, sid);
812 DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n"));
814 /* if it's not a domain group, continue */
815 if (map->sid_name_use!=SID_NAME_DOM_GRP) {
819 DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n"));
825 DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n",(unsigned long)map->gid));
827 grp = getgrgid(map->gid);
829 DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n"));
833 DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX security\n"));
839 /* get a local (alias) group from it's SID */
841 BOOL get_local_group_from_sid(DOM_SID *sid, GROUP_MAP *map)
845 if(!init_group_mapping()) {
846 DEBUG(0,("failed to initialize group mapping\n"));
850 /* The group is in the mapping table */
852 ret = pdb_getgrsid(map, *sid);
858 if ( ( (map->sid_name_use != SID_NAME_ALIAS) &&
859 (map->sid_name_use != SID_NAME_WKN_GRP) )
861 || (getgrgid(map->gid) == NULL) )
867 /* local groups only exist in the group mapping DB so this
871 /* the group isn't in the mapping table.
872 * make one based on the unix information */
876 sid_peek_rid(sid, &alias_rid);
877 map->gid=pdb_group_rid_to_gid(alias_rid);
879 grp = getgrgid(map->gid);
881 DEBUG(3,("get_local_group_from_sid: No unix group for [%ul]\n", map->gid));
885 map->sid_name_use=SID_NAME_ALIAS;
887 fstrcpy(map->nt_name, grp->gr_name);
888 fstrcpy(map->comment, "Local Unix Group");
890 sid_copy(&map->sid, sid);
897 /* get a builtin group from it's SID */
899 BOOL get_builtin_group_from_sid(DOM_SID *sid, GROUP_MAP *map)
905 if(!init_group_mapping()) {
906 DEBUG(0,("failed to initialize group mapping\n"));
911 ret = pdb_getgrsid(map, *sid);
917 if (map->sid_name_use!=SID_NAME_WKN_GRP) {
925 if ( (grp=getgrgid(map->gid)) == NULL) {
934 /****************************************************************************
935 Returns a GROUP_MAP struct based on the gid.
936 ****************************************************************************/
937 BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map)
942 if(!init_group_mapping()) {
943 DEBUG(0,("failed to initialize group mapping\n"));
947 if ( (grp=getgrgid(gid)) == NULL)
951 ret = pdb_getgrgid(map, gid);
962 /****************************************************************************
963 Create a UNIX group on demand.
964 ****************************************************************************/
966 int smb_create_group(char *unix_group, gid_t *new_gid)
974 /* defer to scripts */
976 if ( *lp_addgroup_script() ) {
977 pstrcpy(add_script, lp_addgroup_script());
978 pstring_sub(add_script, "%g", unix_group);
979 ret = smbrun(add_script, (new_gid!=NULL) ? &fd : NULL);
980 DEBUG(ret ? 0 : 3,("smb_create_group: Running the command `%s' gave %d\n",add_script,ret));
988 if (read(fd, output, sizeof(output)) > 0) {
989 *new_gid = (gid_t)strtoul(output, NULL, 10);
995 } else if ( winbind_create_group( unix_group, NULL ) ) {
997 DEBUG(3,("smb_create_group: winbindd created the group (%s)\n",
1002 if (*new_gid == 0) {
1003 struct group *grp = getgrnam(unix_group);
1006 *new_gid = grp->gr_gid;
1012 /****************************************************************************
1013 Delete a UNIX group on demand.
1014 ****************************************************************************/
1016 int smb_delete_group(char *unix_group)
1021 /* defer to scripts */
1023 if ( *lp_delgroup_script() ) {
1024 pstrcpy(del_script, lp_delgroup_script());
1025 pstring_sub(del_script, "%g", unix_group);
1026 ret = smbrun(del_script,NULL);
1027 DEBUG(ret ? 0 : 3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
1031 if ( winbind_delete_group( unix_group ) ) {
1032 DEBUG(3,("smb_delete_group: winbindd deleted the group (%s)\n",
1040 /****************************************************************************
1041 Set a user's primary UNIX group.
1042 ****************************************************************************/
1043 int smb_set_primary_group(const char *unix_group, const char* unix_user)
1048 /* defer to scripts */
1050 if ( *lp_setprimarygroup_script() ) {
1051 pstrcpy(add_script, lp_setprimarygroup_script());
1052 all_string_sub(add_script, "%g", unix_group, sizeof(add_script));
1053 all_string_sub(add_script, "%u", unix_user, sizeof(add_script));
1054 ret = smbrun(add_script,NULL);
1055 flush_pwnam_cache();
1056 DEBUG(ret ? 0 : 3,("smb_set_primary_group: "
1057 "Running the command `%s' gave %d\n",add_script,ret));
1063 if ( winbind_set_user_primary_group( unix_user, unix_group ) ) {
1064 DEBUG(3,("smb_delete_group: winbindd set the group (%s) as the primary group for user (%s)\n",
1065 unix_group, unix_user));
1066 flush_pwnam_cache();
1073 /****************************************************************************
1074 Add a user to a UNIX group.
1075 ****************************************************************************/
1077 int smb_add_user_group(char *unix_group, char *unix_user)
1082 /* defer to scripts */
1084 if ( *lp_addusertogroup_script() ) {
1085 pstrcpy(add_script, lp_addusertogroup_script());
1086 pstring_sub(add_script, "%g", unix_group);
1087 pstring_sub(add_script, "%u", unix_user);
1088 ret = smbrun(add_script,NULL);
1089 DEBUG(ret ? 0 : 3,("smb_add_user_group: Running the command `%s' gave %d\n",add_script,ret));
1095 if ( winbind_add_user_to_group( unix_user, unix_group ) ) {
1096 DEBUG(3,("smb_delete_group: winbindd added user (%s) to the group (%s)\n",
1097 unix_user, unix_group));
1104 /****************************************************************************
1105 Delete a user from a UNIX group
1106 ****************************************************************************/
1108 int smb_delete_user_group(const char *unix_group, const char *unix_user)
1113 /* defer to scripts */
1115 if ( *lp_deluserfromgroup_script() ) {
1116 pstrcpy(del_script, lp_deluserfromgroup_script());
1117 pstring_sub(del_script, "%g", unix_group);
1118 pstring_sub(del_script, "%u", unix_user);
1119 ret = smbrun(del_script,NULL);
1120 DEBUG(ret ? 0 : 3,("smb_delete_user_group: Running the command `%s' gave %d\n",del_script,ret));
1126 if ( winbind_remove_user_from_group( unix_user, unix_group ) ) {
1127 DEBUG(3,("smb_delete_group: winbindd removed user (%s) from the group (%s)\n",
1128 unix_user, unix_group));
1136 NTSTATUS pdb_default_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
1139 return get_group_map_from_sid(sid, map) ?
1140 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1143 NTSTATUS pdb_default_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
1146 return get_group_map_from_gid(gid, map) ?
1147 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1150 NTSTATUS pdb_default_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
1153 return get_group_map_from_ntname(name, map) ?
1154 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1157 NTSTATUS pdb_default_add_group_mapping_entry(struct pdb_methods *methods,
1160 return add_mapping_entry(map, TDB_INSERT) ?
1161 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1164 NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods,
1167 return add_mapping_entry(map, TDB_REPLACE) ?
1168 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1171 NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods,
1174 return group_map_remove(sid) ?
1175 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1178 NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods,
1179 enum SID_NAME_USE sid_name_use,
1180 GROUP_MAP **rmap, int *num_entries,
1183 return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only) ?
1184 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1187 NTSTATUS pdb_default_find_alias(struct pdb_methods *methods,
1188 const char *name, DOM_SID *sid)
1192 if (!pdb_getgrnam(&map, name))
1193 return NT_STATUS_NO_SUCH_ALIAS;
1195 if ((map.sid_name_use != SID_NAME_WKN_GRP) &&
1196 (map.sid_name_use != SID_NAME_ALIAS))
1197 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1199 sid_copy(sid, &map.sid);
1200 return NT_STATUS_OK;
1203 NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
1204 const char *name, uint32 *rid)
1207 enum SID_NAME_USE type;
1213 if (lookup_name(get_global_sam_name(), name, &sid, &type))
1214 return NT_STATUS_ALIAS_EXISTS;
1216 if (!winbind_allocate_rid(&new_rid))
1217 return NT_STATUS_ACCESS_DENIED;
1219 sid_copy(&sid, get_global_sam_sid());
1220 sid_append_rid(&sid, new_rid);
1222 /* Here we allocate the gid */
1223 if (!winbind_sid_to_gid(&gid, &sid)) {
1224 DEBUG(0, ("Could not get gid for new RID\n"));
1225 return NT_STATUS_ACCESS_DENIED;
1229 sid_copy(&map.sid, &sid);
1230 map.sid_name_use = SID_NAME_ALIAS;
1231 fstrcpy(map.nt_name, name);
1232 fstrcpy(map.comment, "");
1234 if (!pdb_add_group_mapping_entry(&map)) {
1235 DEBUG(0, ("Could not add group mapping entry for alias %s\n",
1237 return NT_STATUS_ACCESS_DENIED;
1242 return NT_STATUS_OK;
1245 NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods,
1248 return pdb_delete_group_mapping_entry(*sid) ?
1249 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
1252 NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods,
1254 uint32 start_idx, uint32 max_entries,
1255 uint32 *num_aliases,
1256 struct acct_info **info)
1260 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
1262 if (sid_compare(sid, get_global_sam_sid()) == 0)
1263 type = SID_NAME_ALIAS;
1265 if (sid_compare(sid, &global_sid_Builtin) == 0)
1266 type = SID_NAME_WKN_GRP;
1268 if (!pdb_enum_group_mapping(type, &map, &num_maps, False) ||
1275 if (start_idx > num_maps) {
1281 *num_aliases = num_maps - start_idx;
1283 if (*num_aliases > max_entries)
1284 *num_aliases = max_entries;
1286 *info = SMB_MALLOC_ARRAY(struct acct_info, *num_aliases);
1288 for (i=0; i<*num_aliases; i++) {
1289 fstrcpy((*info)[i].acct_name, map[i+start_idx].nt_name);
1290 fstrcpy((*info)[i].acct_desc, map[i+start_idx].comment);
1291 sid_peek_rid(&map[i].sid, &(*info)[i+start_idx].rid);
1296 return NT_STATUS_OK;
1299 NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods,
1301 struct acct_info *info)
1305 if (!pdb_getgrsid(&map, *sid))
1306 return NT_STATUS_NO_SUCH_ALIAS;
1308 fstrcpy(info->acct_name, map.nt_name);
1309 fstrcpy(info->acct_desc, map.comment);
1310 sid_peek_rid(&map.sid, &info->rid);
1311 return NT_STATUS_OK;
1314 NTSTATUS pdb_default_set_aliasinfo(struct pdb_methods *methods,
1316 struct acct_info *info)
1320 if (!pdb_getgrsid(&map, *sid))
1321 return NT_STATUS_NO_SUCH_ALIAS;
1323 fstrcpy(map.comment, info->acct_desc);
1325 if (!pdb_update_group_mapping_entry(&map))
1326 return NT_STATUS_ACCESS_DENIED;
1328 return NT_STATUS_OK;
1331 NTSTATUS pdb_default_add_aliasmem(struct pdb_methods *methods,
1332 const DOM_SID *alias, const DOM_SID *member)
1334 return add_aliasmem(alias, member);
1337 NTSTATUS pdb_default_del_aliasmem(struct pdb_methods *methods,
1338 const DOM_SID *alias, const DOM_SID *member)
1340 return del_aliasmem(alias, member);
1343 NTSTATUS pdb_default_enum_aliasmem(struct pdb_methods *methods,
1344 const DOM_SID *alias, DOM_SID **members,
1347 return enum_aliasmem(alias, members, num_members);
1350 NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
1351 TALLOC_CTX *mem_ctx,
1352 const DOM_SID *domain_sid,
1353 const DOM_SID *members,
1355 uint32 **alias_rids,
1356 int *num_alias_rids)
1358 DOM_SID *alias_sids;
1359 int i, num_alias_sids;
1365 result = alias_memberships(members, num_members,
1366 &alias_sids, &num_alias_sids);
1368 if (!NT_STATUS_IS_OK(result))
1371 *alias_rids = TALLOC_ARRAY(mem_ctx, uint32, num_alias_sids);
1372 if ((alias_sids != 0) && (*alias_rids == NULL))
1373 return NT_STATUS_NO_MEMORY;
1375 *num_alias_rids = 0;
1377 for (i=0; i<num_alias_sids; i++) {
1378 if (!sid_peek_check_rid(domain_sid, &alias_sids[i],
1379 &(*alias_rids)[*num_alias_rids]))
1381 *num_alias_rids += 1;
1384 SAFE_FREE(alias_sids);
1386 return NT_STATUS_OK;
1389 /**********************************************************************
1390 no ops for passdb backends that don't implement group mapping
1391 *********************************************************************/
1393 NTSTATUS pdb_nop_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
1396 return NT_STATUS_UNSUCCESSFUL;
1399 NTSTATUS pdb_nop_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
1402 return NT_STATUS_UNSUCCESSFUL;
1405 NTSTATUS pdb_nop_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
1408 return NT_STATUS_UNSUCCESSFUL;
1411 NTSTATUS pdb_nop_add_group_mapping_entry(struct pdb_methods *methods,
1414 return NT_STATUS_UNSUCCESSFUL;
1417 NTSTATUS pdb_nop_update_group_mapping_entry(struct pdb_methods *methods,
1420 return NT_STATUS_UNSUCCESSFUL;
1423 NTSTATUS pdb_nop_delete_group_mapping_entry(struct pdb_methods *methods,
1426 return NT_STATUS_UNSUCCESSFUL;
1429 NTSTATUS pdb_nop_enum_group_mapping(struct pdb_methods *methods,
1430 enum SID_NAME_USE sid_name_use,
1431 GROUP_MAP **rmap, int *num_entries,
1434 return NT_STATUS_UNSUCCESSFUL;