summaryrefslogtreecommitdiff
path: root/source3/utils
diff options
context:
space:
mode:
Diffstat (limited to 'source3/utils')
-rw-r--r--source3/utils/net_sam.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c
index 06fc73da4b..dd979bdc6e 100644
--- a/source3/utils/net_sam.c
+++ b/source3/utils/net_sam.c
@@ -507,6 +507,61 @@ static int net_sam_policy(int argc, const char **argv)
* Map a unix group to a domain group
*/
+static NTSTATUS map_unix_group(const struct group *grp, GROUP_MAP *pmap)
+{
+ NTSTATUS status;
+ GROUP_MAP map;
+ const char *grpname, *dom, *name;
+ uint32 rid;
+
+ if (pdb_getgrgid(&map, grp->gr_gid)) {
+ return NT_STATUS_GROUP_EXISTS;
+ }
+
+ map.gid = grp->gr_gid;
+ grpname = grp->gr_name;
+
+ if (lookup_name(tmp_talloc_ctx(), grpname, LOOKUP_NAME_ISOLATED,
+ &dom, &name, NULL, NULL)) {
+
+ const char *tmp = talloc_asprintf(
+ tmp_talloc_ctx(), "Unix Group %s", grp->gr_name);
+
+ DEBUG(5, ("%s exists as %s\\%s, retrying as \"%s\"\n",
+ grpname, dom, name, tmp));
+ grpname = tmp;
+ }
+
+ if (lookup_name(tmp_talloc_ctx(), grpname, LOOKUP_NAME_ISOLATED,
+ NULL, NULL, NULL, NULL)) {
+ DEBUG(3, ("\"%s\" exists, can't map it\n", grp->gr_name));
+ return NT_STATUS_GROUP_EXISTS;
+ }
+
+ fstrcpy(map.nt_name, grpname);
+
+ if (pdb_rid_algorithm()) {
+ rid = algorithmic_pdb_gid_to_group_rid( grp->gr_gid );
+ } else {
+ if (!pdb_new_rid(&rid)) {
+ DEBUG(3, ("Could not get a new RID for %s\n",
+ grp->gr_name));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+
+ sid_compose(&map.sid, get_global_sam_sid(), rid);
+ map.sid_name_use = SID_NAME_DOM_GRP;
+ fstrcpy(map.comment, talloc_asprintf(tmp_talloc_ctx(), "Unix Group %s",
+ grp->gr_name));
+
+ status = pdb_add_group_mapping_entry(&map);
+ if (NT_STATUS_IS_OK(status)) {
+ *pmap = map;
+ }
+ return status;
+}
+
static int net_sam_mapunixgroup(int argc, const char **argv)
{
NTSTATUS status;
@@ -539,6 +594,67 @@ static int net_sam_mapunixgroup(int argc, const char **argv)
}
/*
+ * Remove a group mapping
+ */
+
+static NTSTATUS unmap_unix_group(const struct group *grp, GROUP_MAP *pmap)
+{
+ NTSTATUS status;
+ GROUP_MAP map;
+ const char *grpname;
+ DOM_SID dom_sid;
+
+ map.gid = grp->gr_gid;
+ grpname = grp->gr_name;
+
+ if (!lookup_name(tmp_talloc_ctx(), grpname, LOOKUP_NAME_ISOLATED,
+ NULL, NULL, NULL, NULL)) {
+ DEBUG(3, ("\"%s\" does not exist, can't unmap it\n", grp->gr_name));
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ fstrcpy(map.nt_name, grpname);
+
+ if (!pdb_gid_to_sid(map.gid, &dom_sid)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ status = pdb_delete_group_mapping_entry(dom_sid);
+
+ return status;
+}
+
+static int net_sam_unmapunixgroup(int argc, const char **argv)
+{
+ NTSTATUS status;
+ GROUP_MAP map;
+ struct group *grp;
+
+ if (argc != 1) {
+ d_fprintf(stderr, "usage: net sam unmapunixgroup <name>\n");
+ return -1;
+ }
+
+ grp = getgrnam(argv[0]);
+ if (grp == NULL) {
+ d_fprintf(stderr, "Could not find mapping for group %s.\n", argv[0]);
+ return -1;
+ }
+
+ status = unmap_unix_group(grp, &map);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "Unmapping group %s failed with %s.\n",
+ argv[0], nt_errstr(status));
+ return -1;
+ }
+
+ d_printf("Unmapped unix group %s.\n", argv[0]);
+
+ return 0;
+}
+
+/*
* Create a local group
*/
@@ -1386,6 +1502,8 @@ int net_sam(int argc, const char **argv)
"Delete an existing local group" },
{ "mapunixgroup", net_sam_mapunixgroup,
"Map a unix group to a domain group" },
+ { "unmapunixgroup", net_sam_unmapunixgroup,
+ "Remove a group mapping of an unix group to a domain group" },
{ "addmem", net_sam_addmem,
"Add a member to a group" },
{ "delmem", net_sam_delmem,