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 static TDB_CONTEXT *tdb; /* used for driver files */
26 #define DATABASE_VERSION_V1 1 /* native byte format. */
27 #define DATABASE_VERSION_V2 2 /* le format. */
29 #define GROUP_PREFIX "UNIXGROUP/"
31 /* Alias memberships are stored reverse, as memberships. The performance
32 * critical operation is to determine the aliases a SID is member of, not
33 * listing alias members. So we store a list of alias SIDs a SID is member of
34 * hanging of the member as key.
36 #define MEMBEROF_PREFIX "MEMBEROF/"
38 /****************************************************************************
39 dump the mapping group mapping to a text file
40 ****************************************************************************/
41 char *decode_sid_name_use(fstring group, enum SID_NAME_USE name_use)
43 static fstring group_type;
47 fstrcpy(group_type,"User");
49 case SID_NAME_DOM_GRP:
50 fstrcpy(group_type,"Domain group");
53 fstrcpy(group_type,"Domain");
56 fstrcpy(group_type,"Local group");
58 case SID_NAME_WKN_GRP:
59 fstrcpy(group_type,"Builtin group");
61 case SID_NAME_DELETED:
62 fstrcpy(group_type,"Deleted");
64 case SID_NAME_INVALID:
65 fstrcpy(group_type,"Invalid");
67 case SID_NAME_UNKNOWN:
69 fstrcpy(group_type,"Unknown type");
73 fstrcpy(group, group_type);
77 /****************************************************************************
78 initialise first time the mapping list - called from init_group_mapping()
79 ****************************************************************************/
80 static BOOL default_group_mapping(void)
89 /* Add the Wellknown groups */
91 add_initial_entry(-1, "S-1-5-32-544", SID_NAME_WKN_GRP, "Administrators", "");
92 add_initial_entry(-1, "S-1-5-32-545", SID_NAME_WKN_GRP, "Users", "");
93 add_initial_entry(-1, "S-1-5-32-546", SID_NAME_WKN_GRP, "Guests", "");
94 add_initial_entry(-1, "S-1-5-32-547", SID_NAME_WKN_GRP, "Power Users", "");
95 add_initial_entry(-1, "S-1-5-32-548", SID_NAME_WKN_GRP, "Account Operators", "");
96 add_initial_entry(-1, "S-1-5-32-549", SID_NAME_WKN_GRP, "System Operators", "");
97 add_initial_entry(-1, "S-1-5-32-550", SID_NAME_WKN_GRP, "Print Operators", "");
98 add_initial_entry(-1, "S-1-5-32-551", SID_NAME_WKN_GRP, "Backup Operators", "");
99 add_initial_entry(-1, "S-1-5-32-552", SID_NAME_WKN_GRP, "Replicators", "");
101 /* Add the defaults domain groups */
103 sid_copy(&sid_admins, get_global_sam_sid());
104 sid_append_rid(&sid_admins, DOMAIN_GROUP_RID_ADMINS);
105 sid_to_string(str_admins, &sid_admins);
106 add_initial_entry(-1, str_admins, SID_NAME_DOM_GRP, "Domain Admins", "");
108 sid_copy(&sid_users, get_global_sam_sid());
109 sid_append_rid(&sid_users, DOMAIN_GROUP_RID_USERS);
110 sid_to_string(str_users, &sid_users);
111 add_initial_entry(-1, str_users, SID_NAME_DOM_GRP, "Domain Users", "");
113 sid_copy(&sid_guests, get_global_sam_sid());
114 sid_append_rid(&sid_guests, DOMAIN_GROUP_RID_GUESTS);
115 sid_to_string(str_guests, &sid_guests);
116 add_initial_entry(-1, str_guests, SID_NAME_DOM_GRP, "Domain Guests", "");
121 /****************************************************************************
122 Open the group mapping tdb.
123 ****************************************************************************/
125 static BOOL init_group_mapping(void)
127 static pid_t local_pid;
128 const char *vstring = "INFO/version";
131 if (tdb && local_pid == sys_getpid())
133 tdb = tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
135 DEBUG(0,("Failed to open group mapping database\n"));
139 local_pid = sys_getpid();
141 /* handle a Samba upgrade */
142 tdb_lock_bystring(tdb, vstring, 0);
144 /* Cope with byte-reversed older versions of the db. */
145 vers_id = tdb_fetch_int32(tdb, vstring);
146 if ((vers_id == DATABASE_VERSION_V1) || (IREV(vers_id) == DATABASE_VERSION_V1)) {
147 /* Written on a bigendian machine with old fetch_int code. Save as le. */
148 tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
149 vers_id = DATABASE_VERSION_V2;
152 if (vers_id != DATABASE_VERSION_V2) {
153 tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
154 tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
157 tdb_unlock_bystring(tdb, vstring);
159 /* write a list of default groups */
160 if(!default_group_mapping())
166 /****************************************************************************
167 ****************************************************************************/
168 static BOOL add_mapping_entry(GROUP_MAP *map, int flag)
172 fstring string_sid="";
175 if(!init_group_mapping()) {
176 DEBUG(0,("failed to initialize group mapping\n"));
180 sid_to_string(string_sid, &map->sid);
182 len = tdb_pack(buf, sizeof(buf), "ddff",
183 map->gid, map->sid_name_use, map->nt_name, map->comment);
185 if (len > sizeof(buf))
188 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
190 kbuf.dsize = strlen(key)+1;
194 if (tdb_store(tdb, kbuf, dbuf, flag) != 0) return False;
199 /****************************************************************************
200 initialise first time the mapping list
201 ****************************************************************************/
202 BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_use, const char *nt_name, const char *comment)
206 if(!init_group_mapping()) {
207 DEBUG(0,("failed to initialize group mapping\n"));
212 if (!string_to_sid(&map.sid, sid)) {
213 DEBUG(0, ("string_to_sid failed: %s", sid));
217 map.sid_name_use=sid_name_use;
218 fstrcpy(map.nt_name, nt_name);
219 fstrcpy(map.comment, comment);
221 return pdb_add_group_mapping_entry(&map);
224 /****************************************************************************
225 Return the sid and the type of the unix group.
226 ****************************************************************************/
228 static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map)
235 if(!init_group_mapping()) {
236 DEBUG(0,("failed to initialize group mapping\n"));
240 /* the key is the SID, retrieving is direct */
242 sid_to_string(string_sid, &sid);
243 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
246 kbuf.dsize = strlen(key)+1;
248 dbuf = tdb_fetch(tdb, kbuf);
252 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
253 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
255 SAFE_FREE(dbuf.dptr);
258 DEBUG(3,("get_group_map_from_sid: tdb_unpack failure\n"));
262 sid_copy(&map->sid, &sid);
267 /****************************************************************************
268 Return the sid and the type of the unix group.
269 ****************************************************************************/
271 static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map)
273 TDB_DATA kbuf, dbuf, newkey;
277 if(!init_group_mapping()) {
278 DEBUG(0,("failed to initialize group mapping\n"));
282 /* we need to enumerate the TDB to find the GID */
284 for (kbuf = tdb_firstkey(tdb);
286 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
288 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue;
290 dbuf = tdb_fetch(tdb, kbuf);
294 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
296 string_to_sid(&map->sid, string_sid);
298 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
299 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
301 SAFE_FREE(dbuf.dptr);
304 DEBUG(3,("get_group_map_from_gid: tdb_unpack failure\n"));
309 SAFE_FREE(kbuf.dptr);
317 /****************************************************************************
318 Return the sid and the type of the unix group.
319 ****************************************************************************/
321 static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map)
323 TDB_DATA kbuf, dbuf, newkey;
327 if(!init_group_mapping()) {
328 DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping\n"));
332 /* we need to enumerate the TDB to find the name */
334 for (kbuf = tdb_firstkey(tdb);
336 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
338 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue;
340 dbuf = tdb_fetch(tdb, kbuf);
344 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
346 string_to_sid(&map->sid, string_sid);
348 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
349 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
351 SAFE_FREE(dbuf.dptr);
354 DEBUG(3,("get_group_map_from_ntname: tdb_unpack failure\n"));
358 if (StrCaseCmp(name, map->nt_name)==0) {
359 SAFE_FREE(kbuf.dptr);
367 /****************************************************************************
368 Remove a group mapping entry.
369 ****************************************************************************/
371 static BOOL group_map_remove(const DOM_SID *sid)
377 if(!init_group_mapping()) {
378 DEBUG(0,("failed to initialize group mapping\n"));
382 /* the key is the SID, retrieving is direct */
384 sid_to_string(string_sid, sid);
385 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
388 kbuf.dsize = strlen(key)+1;
390 dbuf = tdb_fetch(tdb, kbuf);
394 SAFE_FREE(dbuf.dptr);
396 if(tdb_delete(tdb, kbuf) != TDB_SUCCESS)
402 /****************************************************************************
403 Enumerate the group mapping.
404 ****************************************************************************/
406 static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
407 int *num_entries, BOOL unix_only)
409 TDB_DATA kbuf, dbuf, newkey;
417 if(!init_group_mapping()) {
418 DEBUG(0,("failed to initialize group mapping\n"));
425 for (kbuf = tdb_firstkey(tdb);
427 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
429 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0)
432 dbuf = tdb_fetch(tdb, kbuf);
436 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
438 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
439 &map.gid, &map.sid_name_use, &map.nt_name, &map.comment);
441 SAFE_FREE(dbuf.dptr);
444 DEBUG(3,("enum_group_mapping: tdb_unpack failure\n"));
448 /* list only the type or everything if UNKNOWN */
449 if (sid_name_use!=SID_NAME_UNKNOWN && sid_name_use!=map.sid_name_use) {
450 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
454 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
455 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
459 string_to_sid(&map.sid, string_sid);
461 decode_sid_name_use(group_type, map.sid_name_use);
462 DEBUG(11,("enum_group_mapping: returning group %s of type %s\n", map.nt_name ,group_type));
464 mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
466 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
473 mapt[entries].gid = map.gid;
474 sid_copy( &mapt[entries].sid, &map.sid);
475 mapt[entries].sid_name_use = map.sid_name_use;
476 fstrcpy(mapt[entries].nt_name, map.nt_name);
477 fstrcpy(mapt[entries].comment, map.comment);
483 *num_entries=entries;
488 /* This operation happens on session setup, so it should better be fast. We
489 * store a list of aliases a SID is member of hanging off MEMBEROF/SID. */
491 static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num)
493 fstring key, string_sid;
500 if (!init_group_mapping()) {
501 DEBUG(0,("failed to initialize group mapping\n"));
502 return NT_STATUS_ACCESS_DENIED;
505 sid_to_string(string_sid, sid);
506 slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid);
508 kbuf.dsize = strlen(key)+1;
511 dbuf = tdb_fetch(tdb, kbuf);
513 if (dbuf.dptr == NULL) {
519 while (next_token(&p, string_sid, " ", sizeof(string_sid))) {
523 if (!string_to_sid(&alias, string_sid))
526 add_sid_to_array(&alias, sids, num);
529 return NT_STATUS_NO_MEMORY;
532 SAFE_FREE(dbuf.dptr);
536 static BOOL is_aliasmem(const DOM_SID *alias, const DOM_SID *member)
541 /* This feels the wrong way round, but the on-disk data structure
542 * dictates it this way. */
543 if (!NT_STATUS_IS_OK(alias_memberships(member, &sids, &num)))
546 for (i=0; i<num; i++) {
547 if (sid_compare(alias, &sids[i]) == 0) {
556 static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
562 char *new_memberstring;
565 if(!init_group_mapping()) {
566 DEBUG(0,("failed to initialize group mapping\n"));
567 return NT_STATUS_ACCESS_DENIED;
570 if (!get_group_map_from_sid(*alias, &map))
571 return NT_STATUS_NO_SUCH_ALIAS;
573 if ( (map.sid_name_use != SID_NAME_ALIAS) &&
574 (map.sid_name_use != SID_NAME_WKN_GRP) )
575 return NT_STATUS_NO_SUCH_ALIAS;
577 if (is_aliasmem(alias, member))
578 return NT_STATUS_MEMBER_IN_ALIAS;
580 sid_to_string(string_sid, member);
581 slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid);
583 kbuf.dsize = strlen(key)+1;
586 dbuf = tdb_fetch(tdb, kbuf);
588 sid_to_string(string_sid, alias);
590 if (dbuf.dptr != NULL) {
591 asprintf(&new_memberstring, "%s %s", (char *)(dbuf.dptr),
594 new_memberstring = strdup(string_sid);
597 if (new_memberstring == NULL)
598 return NT_STATUS_NO_MEMORY;
600 SAFE_FREE(dbuf.dptr);
601 dbuf.dsize = strlen(new_memberstring)+1;
602 dbuf.dptr = new_memberstring;
604 result = tdb_store(tdb, kbuf, dbuf, 0);
606 SAFE_FREE(new_memberstring);
608 return (result == 0 ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED);
611 struct aliasmem_closure {
612 const DOM_SID *alias;
617 static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data,
620 struct aliasmem_closure *closure = (struct aliasmem_closure *)state;
622 fstring alias_string;
624 if (strncmp(key.dptr, MEMBEROF_PREFIX,
625 strlen(MEMBEROF_PREFIX)) != 0)
630 while (next_token(&p, alias_string, " ", sizeof(alias_string))) {
632 DOM_SID alias, member;
633 const char *member_string;
636 if (!string_to_sid(&alias, alias_string))
639 if (sid_compare(closure->alias, &alias) != 0)
642 /* Ok, we found the alias we're looking for in the membership
643 * list currently scanned. The key represents the alias
644 * member. Add that. */
646 member_string = strchr(key.dptr, '/');
648 /* Above we tested for MEMBEROF_PREFIX which includes the
651 SMB_ASSERT(member_string != NULL);
654 if (!string_to_sid(&member, member_string))
657 add_sid_to_array(&member, closure->sids, closure->num);
663 static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num)
666 struct aliasmem_closure closure;
668 if(!init_group_mapping()) {
669 DEBUG(0,("failed to initialize group mapping\n"));
670 return NT_STATUS_ACCESS_DENIED;
673 if (!get_group_map_from_sid(*alias, &map))
674 return NT_STATUS_NO_SUCH_ALIAS;
676 if ( (map.sid_name_use != SID_NAME_ALIAS) &&
677 (map.sid_name_use != SID_NAME_WKN_GRP) )
678 return NT_STATUS_NO_SUCH_ALIAS;
683 closure.alias = alias;
687 tdb_traverse(tdb, collect_aliasmem, &closure);
691 static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
702 result = alias_memberships(member, &sids, &num);
704 if (!NT_STATUS_IS_OK(result))
707 for (i=0; i<num; i++) {
708 if (sid_compare(&sids[i], alias) == 0) {
716 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
720 sids[i] = sids[num-1];
724 sid_to_string(sid_string, member);
725 slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, sid_string);
727 kbuf.dsize = strlen(key)+1;
731 return tdb_delete(tdb, kbuf) == 0 ?
732 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
734 member_string = strdup("");
736 if (member_string == NULL) {
738 return NT_STATUS_NO_MEMORY;
741 for (i=0; i<num; i++) {
742 char *s = member_string;
744 sid_to_string(sid_string, &sids[i]);
745 asprintf(&member_string, "%s %s", s, sid_string);
748 if (member_string == NULL) {
750 return NT_STATUS_NO_MEMORY;
754 dbuf.dsize = strlen(member_string)+1;
755 dbuf.dptr = member_string;
757 result = tdb_store(tdb, kbuf, dbuf, 0) == 0 ?
758 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
761 SAFE_FREE(member_string);
768 * High level functions
769 * better to use them than the lower ones.
771 * we are checking if the group is in the mapping file
772 * and if the group is an existing unix group
776 /* get a domain group from it's SID */
778 BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map)
783 if(!init_group_mapping()) {
784 DEBUG(0,("failed to initialize group mapping\n"));
788 DEBUG(10, ("get_domain_group_from_sid\n"));
790 /* if the group is NOT in the database, it CAN NOT be a domain group */
793 ret = pdb_getgrsid(map, sid);
799 DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n"));
801 /* if it's not a domain group, continue */
802 if (map->sid_name_use!=SID_NAME_DOM_GRP) {
806 DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n"));
812 DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n",(unsigned long)map->gid));
814 grp = getgrgid(map->gid);
816 DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n"));
820 DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX security\n"));
826 /* get a local (alias) group from it's SID */
828 BOOL get_local_group_from_sid(DOM_SID *sid, GROUP_MAP *map)
832 if(!init_group_mapping()) {
833 DEBUG(0,("failed to initialize group mapping\n"));
837 /* The group is in the mapping table */
839 ret = pdb_getgrsid(map, *sid);
845 if ( ( (map->sid_name_use != SID_NAME_ALIAS) &&
846 (map->sid_name_use != SID_NAME_WKN_GRP) )
848 || (getgrgid(map->gid) == NULL) )
854 /* local groups only exist in the group mapping DB so this
858 /* the group isn't in the mapping table.
859 * make one based on the unix information */
863 sid_peek_rid(sid, &alias_rid);
864 map->gid=pdb_group_rid_to_gid(alias_rid);
866 grp = getgrgid(map->gid);
868 DEBUG(3,("get_local_group_from_sid: No unix group for [%ul]\n", map->gid));
872 map->sid_name_use=SID_NAME_ALIAS;
874 fstrcpy(map->nt_name, grp->gr_name);
875 fstrcpy(map->comment, "Local Unix Group");
877 sid_copy(&map->sid, sid);
884 /* get a builtin group from it's SID */
886 BOOL get_builtin_group_from_sid(DOM_SID *sid, GROUP_MAP *map)
892 if(!init_group_mapping()) {
893 DEBUG(0,("failed to initialize group mapping\n"));
898 ret = pdb_getgrsid(map, *sid);
904 if (map->sid_name_use!=SID_NAME_WKN_GRP) {
912 if ( (grp=getgrgid(map->gid)) == NULL) {
921 /****************************************************************************
922 Returns a GROUP_MAP struct based on the gid.
923 ****************************************************************************/
924 BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map)
929 if(!init_group_mapping()) {
930 DEBUG(0,("failed to initialize group mapping\n"));
934 if ( (grp=getgrgid(gid)) == NULL)
938 * make a group map from scratch if doesn't exist.
942 ret = pdb_getgrgid(map, gid);
947 map->sid_name_use=SID_NAME_ALIAS;
949 /* interim solution until we have a last RID allocated */
951 sid_copy(&map->sid, get_global_sam_sid());
952 sid_append_rid(&map->sid, pdb_gid_to_group_rid(gid));
954 fstrcpy(map->nt_name, grp->gr_name);
955 fstrcpy(map->comment, "Local Unix Group");
961 /****************************************************************************
962 Create a UNIX group on demand.
963 ****************************************************************************/
965 int smb_create_group(char *unix_group, gid_t *new_gid)
973 /* defer to scripts */
975 if ( *lp_addgroup_script() ) {
976 pstrcpy(add_script, lp_addgroup_script());
977 pstring_sub(add_script, "%g", unix_group);
978 ret = smbrun(add_script, (new_gid!=NULL) ? &fd : NULL);
979 DEBUG(3,("smb_create_group: Running the command `%s' gave %d\n",add_script,ret));
987 if (read(fd, output, sizeof(output)) > 0) {
988 *new_gid = (gid_t)strtoul(output, NULL, 10);
994 } else if ( winbind_create_group( unix_group, NULL ) ) {
996 DEBUG(3,("smb_create_group: winbindd created the group (%s)\n",
1001 if (*new_gid == 0) {
1002 struct group *grp = getgrnam(unix_group);
1005 *new_gid = grp->gr_gid;
1011 /****************************************************************************
1012 Delete a UNIX group on demand.
1013 ****************************************************************************/
1015 int smb_delete_group(char *unix_group)
1020 /* defer to scripts */
1022 if ( *lp_delgroup_script() ) {
1023 pstrcpy(del_script, lp_delgroup_script());
1024 pstring_sub(del_script, "%g", unix_group);
1025 ret = smbrun(del_script,NULL);
1026 DEBUG(3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
1030 if ( winbind_delete_group( unix_group ) ) {
1031 DEBUG(3,("smb_delete_group: winbindd deleted the group (%s)\n",
1039 /****************************************************************************
1040 Set a user's primary UNIX group.
1041 ****************************************************************************/
1042 int smb_set_primary_group(const char *unix_group, const char* unix_user)
1047 /* defer to scripts */
1049 if ( *lp_setprimarygroup_script() ) {
1050 pstrcpy(add_script, lp_setprimarygroup_script());
1051 all_string_sub(add_script, "%g", unix_group, sizeof(add_script));
1052 all_string_sub(add_script, "%u", unix_user, sizeof(add_script));
1053 ret = smbrun(add_script,NULL);
1054 DEBUG(3,("smb_set_primary_group: "
1055 "Running the command `%s' gave %d\n",add_script,ret));
1061 if ( winbind_set_user_primary_group( unix_user, unix_group ) ) {
1062 DEBUG(3,("smb_delete_group: winbindd set the group (%s) as the primary group for user (%s)\n",
1063 unix_group, unix_user));
1070 /****************************************************************************
1071 Add a user to a UNIX group.
1072 ****************************************************************************/
1074 int smb_add_user_group(char *unix_group, char *unix_user)
1079 /* defer to scripts */
1081 if ( *lp_addusertogroup_script() ) {
1082 pstrcpy(add_script, lp_addusertogroup_script());
1083 pstring_sub(add_script, "%g", unix_group);
1084 pstring_sub(add_script, "%u", unix_user);
1085 ret = smbrun(add_script,NULL);
1086 DEBUG(3,("smb_add_user_group: Running the command `%s' gave %d\n",add_script,ret));
1092 if ( winbind_add_user_to_group( unix_user, unix_group ) ) {
1093 DEBUG(3,("smb_delete_group: winbindd added user (%s) to the group (%s)\n",
1094 unix_user, unix_group));
1101 /****************************************************************************
1102 Delete a user from a UNIX group
1103 ****************************************************************************/
1105 int smb_delete_user_group(const char *unix_group, const char *unix_user)
1110 /* defer to scripts */
1112 if ( *lp_deluserfromgroup_script() ) {
1113 pstrcpy(del_script, lp_deluserfromgroup_script());
1114 pstring_sub(del_script, "%g", unix_group);
1115 pstring_sub(del_script, "%u", unix_user);
1116 ret = smbrun(del_script,NULL);
1117 DEBUG(3,("smb_delete_user_group: Running the command `%s' gave %d\n",del_script,ret));
1123 if ( winbind_remove_user_from_group( unix_user, unix_group ) ) {
1124 DEBUG(3,("smb_delete_group: winbindd removed user (%s) from the group (%s)\n",
1125 unix_user, unix_group));
1133 NTSTATUS pdb_default_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
1136 return get_group_map_from_sid(sid, map) ?
1137 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1140 NTSTATUS pdb_default_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
1143 return get_group_map_from_gid(gid, map) ?
1144 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1147 NTSTATUS pdb_default_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
1150 return get_group_map_from_ntname(name, map) ?
1151 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1154 NTSTATUS pdb_default_add_group_mapping_entry(struct pdb_methods *methods,
1157 return add_mapping_entry(map, TDB_INSERT) ?
1158 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1161 NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods,
1164 return add_mapping_entry(map, TDB_REPLACE) ?
1165 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1168 NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods,
1171 return group_map_remove(&sid) ?
1172 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1175 NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods,
1176 enum SID_NAME_USE sid_name_use,
1177 GROUP_MAP **rmap, int *num_entries,
1180 return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only) ?
1181 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1184 NTSTATUS pdb_default_find_alias(struct pdb_methods *methods,
1185 const char *name, DOM_SID *sid)
1189 if (!pdb_getgrnam(&map, name))
1190 return NT_STATUS_NO_SUCH_ALIAS;
1192 if ((map.sid_name_use != SID_NAME_WKN_GRP) &&
1193 (map.sid_name_use != SID_NAME_ALIAS))
1194 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1196 sid_copy(sid, &map.sid);
1197 return NT_STATUS_OK;
1200 NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
1201 const char *name, uint32 *rid)
1204 enum SID_NAME_USE type;
1210 if (lookup_name(get_global_sam_name(), name, &sid, &type))
1211 return NT_STATUS_ALIAS_EXISTS;
1213 if (!winbind_allocate_rid(&new_rid))
1214 return NT_STATUS_ACCESS_DENIED;
1216 sid_copy(&sid, get_global_sam_sid());
1217 sid_append_rid(&sid, new_rid);
1219 /* Here we allocate the gid */
1220 if (!winbind_sid_to_gid(&gid, &sid)) {
1221 DEBUG(0, ("Could not get gid for new RID\n"));
1222 return NT_STATUS_ACCESS_DENIED;
1226 sid_copy(&map.sid, &sid);
1227 map.sid_name_use = SID_NAME_ALIAS;
1228 fstrcpy(map.nt_name, name);
1229 fstrcpy(map.comment, "");
1231 if (!pdb_add_group_mapping_entry(&map)) {
1232 DEBUG(0, ("Could not add group mapping entry for alias %s\n",
1234 return NT_STATUS_ACCESS_DENIED;
1239 return NT_STATUS_OK;
1242 NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods,
1245 return pdb_delete_group_mapping_entry(*sid) ?
1246 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
1249 NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods,
1251 uint32 start_idx, uint32 max_entries,
1252 uint32 *num_aliases,
1253 struct acct_info **info)
1255 extern DOM_SID global_sid_Builtin;
1259 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
1261 if (sid_compare(sid, get_global_sam_sid()) == 0)
1262 type = SID_NAME_ALIAS;
1264 if (sid_compare(sid, &global_sid_Builtin) == 0)
1265 type = SID_NAME_WKN_GRP;
1267 if (!pdb_enum_group_mapping(type, &map, &num_maps, False) ||
1274 if (start_idx > num_maps) {
1280 *num_aliases = num_maps - start_idx;
1282 if (*num_aliases > max_entries)
1283 *num_aliases = max_entries;
1285 *info = malloc(sizeof(struct acct_info) * (*num_aliases));
1287 for (i=0; i<*num_aliases; i++) {
1288 fstrcpy((*info)[i].acct_name, map[i+start_idx].nt_name);
1289 fstrcpy((*info)[i].acct_desc, map[i+start_idx].comment);
1290 sid_peek_rid(&map[i].sid, &(*info)[i+start_idx].rid);
1295 return NT_STATUS_OK;
1298 NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods,
1300 struct acct_info *info)
1304 if (!pdb_getgrsid(&map, *sid))
1305 return NT_STATUS_NO_SUCH_ALIAS;
1307 fstrcpy(info->acct_name, map.nt_name);
1308 fstrcpy(info->acct_desc, map.comment);
1309 sid_peek_rid(&map.sid, &info->rid);
1310 return NT_STATUS_OK;
1313 NTSTATUS pdb_default_set_aliasinfo(struct pdb_methods *methods,
1315 struct acct_info *info)
1319 if (!pdb_getgrsid(&map, *sid))
1320 return NT_STATUS_NO_SUCH_ALIAS;
1322 fstrcpy(map.comment, info->acct_desc);
1324 if (!pdb_update_group_mapping_entry(&map))
1325 return NT_STATUS_ACCESS_DENIED;
1327 return NT_STATUS_OK;
1330 NTSTATUS pdb_default_add_aliasmem(struct pdb_methods *methods,
1331 const DOM_SID *alias, const DOM_SID *member)
1333 return add_aliasmem(alias, member);
1336 NTSTATUS pdb_default_del_aliasmem(struct pdb_methods *methods,
1337 const DOM_SID *alias, const DOM_SID *member)
1339 return del_aliasmem(alias, member);
1342 NTSTATUS pdb_default_enum_aliasmem(struct pdb_methods *methods,
1343 const DOM_SID *alias, DOM_SID **members,
1346 return enum_aliasmem(alias, members, num_members);
1349 NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
1351 DOM_SID **aliases, int *num)
1353 return alias_memberships(sid, aliases, num);
1356 /**********************************************************************
1357 no ops for passdb backends that don't implement group mapping
1358 *********************************************************************/
1360 NTSTATUS pdb_nop_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
1363 return NT_STATUS_UNSUCCESSFUL;
1366 NTSTATUS pdb_nop_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
1369 return NT_STATUS_UNSUCCESSFUL;
1372 NTSTATUS pdb_nop_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
1375 return NT_STATUS_UNSUCCESSFUL;
1378 NTSTATUS pdb_nop_add_group_mapping_entry(struct pdb_methods *methods,
1381 return NT_STATUS_UNSUCCESSFUL;
1384 NTSTATUS pdb_nop_update_group_mapping_entry(struct pdb_methods *methods,
1387 return NT_STATUS_UNSUCCESSFUL;
1390 NTSTATUS pdb_nop_delete_group_mapping_entry(struct pdb_methods *methods,
1393 return NT_STATUS_UNSUCCESSFUL;
1396 NTSTATUS pdb_nop_enum_group_mapping(struct pdb_methods *methods,
1397 enum SID_NAME_USE sid_name_use,
1398 GROUP_MAP **rmap, int *num_entries,
1401 return NT_STATUS_UNSUCCESSFUL;
1404 /****************************************************************************
1405 These need to be redirected through pdb_interface.c
1406 ****************************************************************************/
1407 BOOL pdb_get_dom_grp_info(const DOM_SID *sid, struct acct_info *info)
1413 res = get_domain_group_from_sid(*sid, &map);
1419 fstrcpy(info->acct_name, map.nt_name);
1420 fstrcpy(info->acct_desc, map.comment);
1421 sid_peek_rid(sid, &info->rid);
1425 BOOL pdb_set_dom_grp_info(const DOM_SID *sid, const struct acct_info *info)
1429 if (!get_domain_group_from_sid(*sid, &map))
1432 fstrcpy(map.nt_name, info->acct_name);
1433 fstrcpy(map.comment, info->acct_desc);
1435 return pdb_update_group_mapping_entry(&map);