Make "net ads listmem" also work for domain groups
[ira/wip.git] / source3 / utils / net_sam.c
index eea22c0dc2038514f4f03b922e05d7ca0474373a..ddf4d4e16214f992d4acf31a26fa1018d84da618 100644 (file)
@@ -921,6 +921,34 @@ static int net_sam_unmapunixgroup(struct net_context *c, int argc, const char **
        return 0;
 }
 
+/*
+ * Create a domain group
+ */
+
+static int net_sam_createdomaingroup(struct net_context *c, int argc,
+                                    const char **argv)
+{
+       NTSTATUS status;
+       uint32 rid;
+
+       if (argc != 1 || c->display_usage) {
+               d_fprintf(stderr, "usage: net sam createdomaingroup <name>\n");
+               return -1;
+       }
+
+       status = pdb_create_dom_group(talloc_tos(), argv[0], &rid);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "Creating %s failed with %s\n",
+                         argv[0], nt_errstr(status));
+               return -1;
+       }
+
+       d_printf("Created domain group %s with RID %d\n", argv[0], rid);
+
+       return 0;
+}
+
 /*
  * Create a local group
  */
@@ -1186,6 +1214,8 @@ static int net_sam_listmem(struct net_context *c, int argc, const char **argv)
 {
        const char *groupdomain, *groupname;
        DOM_SID group;
+       DOM_SID *members = NULL;
+       size_t i, num_members = 0;
        enum lsa_SidType grouptype;
        NTSTATUS status;
 
@@ -1202,36 +1232,55 @@ static int net_sam_listmem(struct net_context *c, int argc, const char **argv)
 
        if ((grouptype == SID_NAME_ALIAS) ||
            (grouptype == SID_NAME_WKN_GRP)) {
-               DOM_SID *members = NULL;
-               size_t i, num_members = 0;
-
-               status = pdb_enum_aliasmem(&group, &members, &num_members);
+               status = pdb_enum_aliasmem(&group, talloc_tos(), &members,
+                                          &num_members);
+               if (!NT_STATUS_IS_OK(status)) {
+                       d_fprintf(stderr, "Listing group members failed with "
+                                 "%s\n", nt_errstr(status));
+                       return -1;
+               }
+       } else if (grouptype == SID_NAME_DOM_GRP) {
+               uint32_t *rids;
 
+               status = pdb_enum_group_members(talloc_tos(), &group,
+                                               &rids, &num_members);
                if (!NT_STATUS_IS_OK(status)) {
                        d_fprintf(stderr, "Listing group members failed with "
                                  "%s\n", nt_errstr(status));
                        return -1;
                }
 
-               d_printf("%s\\%s has %u members\n", groupdomain, groupname,
-                        (unsigned int)num_members);
-               for (i=0; i<num_members; i++) {
-                       const char *dom, *name;
-                       if (lookup_sid(talloc_tos(), &members[i],
-                                      &dom, &name, NULL)) {
-                               d_printf(" %s\\%s\n", dom, name);
-                       } else {
-                               d_printf(" %s\n", sid_string_tos(&members[i]));
-                       }
+               members = talloc_array(talloc_tos(), struct dom_sid,
+                                      num_members);
+               if (members == NULL) {
+                       TALLOC_FREE(rids);
+                       return -1;
                }
 
-               TALLOC_FREE(members);
+               for (i=0; i<num_members; i++) {
+                       sid_compose(&members[i], get_global_sam_sid(),
+                                   rids[i]);
+               }
+               TALLOC_FREE(rids);
        } else {
                d_fprintf(stderr, "Can only list local group members so far.\n"
                          "%s is a %s\n", argv[0], sid_type_lookup(grouptype));
                return -1;
        }
 
+       d_printf("%s\\%s has %u members\n", groupdomain, groupname,
+                (unsigned int)num_members);
+       for (i=0; i<num_members; i++) {
+               const char *dom, *name;
+               if (lookup_sid(talloc_tos(), &members[i], &dom, &name, NULL)) {
+                       d_printf(" %s\\%s\n", dom, name);
+               } else {
+                       d_printf(" %s\n", sid_string_tos(&members[i]));
+               }
+       }
+
+               TALLOC_FREE(members);
+
        return 0;
 }
 
@@ -1490,7 +1539,7 @@ static int net_sam_provision(struct net_context *c, int argc, const char **argv)
                uname = talloc_strdup(tc, "domusers");
                wname = talloc_strdup(tc, "Domain Users");
                dn = talloc_asprintf(tc, "cn=%s,%s", "domusers", lp_ldap_group_suffix());
-               gidstr = talloc_asprintf(tc, "%d", domusers_gid);
+               gidstr = talloc_asprintf(tc, "%u", (unsigned int)domusers_gid);
                gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
 
                if (!uname || !wname || !dn || !gidstr || !gtype) {
@@ -1545,7 +1594,7 @@ domu_done:
                uname = talloc_strdup(tc, "domadmins");
                wname = talloc_strdup(tc, "Domain Admins");
                dn = talloc_asprintf(tc, "cn=%s,%s", "domadmins", lp_ldap_group_suffix());
-               gidstr = talloc_asprintf(tc, "%d", domadmins_gid);
+               gidstr = talloc_asprintf(tc, "%u", (unsigned int)domadmins_gid);
                gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
 
                if (!uname || !wname || !dn || !gidstr || !gtype) {
@@ -1608,8 +1657,8 @@ doma_done:
                }
                name = talloc_strdup(tc, "Administrator");
                dn = talloc_asprintf(tc, "uid=Administrator,%s", lp_ldap_user_suffix());
-               uidstr = talloc_asprintf(tc, "%d", uid);
-               gidstr = talloc_asprintf(tc, "%d", domadmins_gid);
+               uidstr = talloc_asprintf(tc, "%u", (unsigned int)uid);
+               gidstr = talloc_asprintf(tc, "%u", (unsigned int)domadmins_gid);
                dir = talloc_sub_specified(tc, lp_template_homedir(),
                                                "Administrator",
                                                get_global_sam_name(),
@@ -1699,8 +1748,8 @@ doma_done:
                sid_compose(&sid, get_global_sam_sid(), DOMAIN_USER_RID_GUEST);
 
                dn = talloc_asprintf(tc, "uid=%s,%s", pwd->pw_name, lp_ldap_user_suffix ());
-               uidstr = talloc_asprintf(tc, "%d", pwd->pw_uid);
-               gidstr = talloc_asprintf(tc, "%d", pwd->pw_gid);
+               uidstr = talloc_asprintf(tc, "%u", (unsigned int)pwd->pw_uid);
+               gidstr = talloc_asprintf(tc, "%u", (unsigned int)pwd->pw_gid);
                if (!dn || !uidstr || !gidstr) {
                        d_fprintf(stderr, "Out of Memory!\n");
                        goto failed;
@@ -1765,7 +1814,7 @@ doma_done:
                uname = talloc_strdup(tc, "domguests");
                wname = talloc_strdup(tc, "Domain Guests");
                dn = talloc_asprintf(tc, "cn=%s,%s", "domguests", lp_ldap_group_suffix());
-               gidstr = talloc_asprintf(tc, "%d", pwd->pw_gid);
+               gidstr = talloc_asprintf(tc, "%u", (unsigned int)pwd->pw_gid);
                gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
 
                if (!uname || !wname || !dn || !gidstr || !gtype) {
@@ -1829,6 +1878,14 @@ int net_sam(struct net_context *c, int argc, const char **argv)
                        "net sam createlocalgroup\n"
                        "    Create a new local group"
                },
+               {
+                       "createdomaingroup",
+                       net_sam_createdomaingroup,
+                       NET_TRANSPORT_LOCAL,
+                       "Create a new group",
+                       "net sam createdomaingroup\n"
+                       "    Create a new group"
+               },
                {
                        "deletelocalgroup",
                        net_sam_deletelocalgroup,