- lib/unix_sec_ctxt.c
authorLuke Leighton <lkcl@samba.org>
Mon, 7 Dec 1998 17:23:48 +0000 (17:23 +0000)
committerLuke Leighton <lkcl@samba.org>
Mon, 7 Dec 1998 17:23:48 +0000 (17:23 +0000)
attempt at taking lib/uid.c and getting a unix security context
change module that is independent of "cnums" and "snums".
a security context is needed for pipes, not just IPC$ or other
services.

- group database API

added add_group/alias_member, del_group/alias_member,
del_group/alias_entry functions.  del_builtin_entry() is
deliberately set to NULL to cause an exception, you cannot
delete builtin aliases.

- parse_lsa.c srv_lsa.c

fixed lookup_names code, it was a load of trash and didn't do
anything.

- cmd_samr.c rpcclient.c srv_samr.c

added "deletegroup", "deletealias", "delaliasmem", "delgroupmem",
"addgroupmem", "addaliasmem", "createalias", "creategroup", to
both client and server code.

server code calls into unix stubs right now, which don't actually
do anything.  the only instance where they are expected to do
anything is in appliance mode NOT even in the ldap code or anything.

client code modified to call samr_lookup_names() for group code
(because we can) and lsa_lookup_names() for alias code (because
we have to).

- srv_lookup.c

oops, lookup on unsplit name, we got lookup on DOMAIN, DOMAIN\name
instead of DOMAIN, name.
(This used to be commit b8175702ef61b8b37b078f38e81452c00a5e2986)

23 files changed:
source3/Makefile.in
source3/groupdb/aliasdb.c
source3/groupdb/aliasfile.c
source3/groupdb/aliasunix.c
source3/groupdb/builtindb.c
source3/groupdb/builtinunix.c
source3/groupdb/groupdb.c
source3/groupdb/groupfile.c
source3/groupdb/groupunix.c
source3/include/proto.h
source3/include/rpc_samr.h
source3/include/smb.h
source3/lsarpcd/srv_lsa.c
source3/rpc_client/cli_lsarpc.c
source3/rpc_client/cli_samr.c
source3/rpc_parse/parse_lsa.c
source3/rpc_parse/parse_misc.c
source3/rpc_parse/parse_samr.c
source3/rpc_server/srv_lookup.c
source3/rpc_server/srv_lsa.c
source3/rpc_server/srv_samr.c
source3/rpcclient/cmd_samr.c
source3/rpcclient/rpcclient.c

index a48661877061c4a34c4906bdcdb70d04db83ffdb..d288767d0ecd33bca66128e2d8c9a65daab2f9e0 100644 (file)
@@ -105,7 +105,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
          lib/bitmap.o lib/crc32.o lib/util_sid.o lib/snprintf.o \
                lib/util_str.o lib/util_unistr.o \
                lib/util_file.o mem_man/mem_man.o \
-               lib/util_sock.o
+               lib/util_sock.o lib/unix_sec_ctxt.c
 
 
 UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
index 011eee0f3dd33500008fc46819417651e9cb3b61..b787012b4d2729d4dc935deb0dc8a0a02d15e2a4 100644 (file)
@@ -348,11 +348,25 @@ LOCAL_GRP *getaliasent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem)
 
 /************************************************************************
  Routine to add an entry to the alias database file.
+ on entry, the entry is added by name.
+ on exit, the RID is expected to have been set.
 *************************************************************************/
-
-BOOL add_alias_entry(LOCAL_GRP *newals)
+BOOL add_alias_entry(LOCAL_GRP *newgrp)
+{
+       BOOL ret;
+       if (newgrp->rid != 0xffffffff)
 {
-       return aldb_ops->add_alias_entry(newals);
+               DEBUG(0,("add_alias_entry - RID must be 0xffffffff, \
+database instance is responsible for allocating the RID, not you.\n"));
+               return False;
+       }
+       ret = aldb_ops->add_alias_entry(newgrp);
+       if (newgrp->rid == 0xffffffff)
+       {
+               DEBUG(0,("add_alias_entry - RID has not been set by database\n"));
+               return False;
+       }
+       return ret;
 }
 
 /************************************************************************
@@ -365,6 +379,29 @@ BOOL mod_alias_entry(LOCAL_GRP* als)
        return aldb_ops->mod_alias_entry(als);
 }
 
+/************************************************************************
+ Routine to delete alias database entry matching by rid.
+************************************************************************/
+BOOL del_alias_entry(uint32 rid)
+{
+       return aldb_ops->del_alias_entry(rid);
+}
+
+/************************************************************************
+ Routine to add a member to an entry in the alias database file.
+*************************************************************************/
+BOOL add_alias_member(uint32 rid, DOM_SID *member_sid)
+{
+       return aldb_ops->add_alias_member(rid, member_sid);
+}
+
+/************************************************************************
+ Routine to delete a member from an entry in the alias database file.
+*************************************************************************/
+BOOL del_alias_member(uint32 rid, DOM_SID *member_sid)
+{
+       return aldb_ops->del_alias_member(rid, member_sid);
+}
 /************************************************************************
  Routine to search alias database by name.
 *************************************************************************/
index 4ae2c25b943193acf3a6b979d566c06cc58b0727..00638f941163471813edb390194cdedb58e4c814 100644 (file)
@@ -235,11 +235,7 @@ static BOOL add_alsfileals_entry(LOCAL_GRP *newals)
 
 /************************************************************************
  Routine to search the aliasdb file for an entry matching the aliasname.
- and then modify its alias entry. We can't use the startalspwent()/
- getalspwent()/endalspwent() interfaces here as we depend on looking
- in the actual file to decide how much room we have to write data.
- override = False, normal
- override = True, override XXXXXXXX'd out alias or NO PASS
+ and then modify its alias entry. 
 ************************************************************************/
 
 static BOOL mod_alsfileals_entry(LOCAL_GRP* als)
index f9b93bbce439ee17e2d761e478817520e4fdcd40..f9537ddeb4c6a98a1a7851ee1eb04c5410d10d67 100644 (file)
@@ -224,11 +224,7 @@ static BOOL add_alsunixgrp_entry(LOCAL_GRP *newals)
 
 /************************************************************************
  Routine to search the alspasswd file for an entry matching the aliasname.
- and then modify its alias entry. We can't use the startalspwent()/
- getalspwent()/endalspwent() interfaces here as we depend on looking
- in the actual file to decide how much room we have to write data.
- override = False, normal
- override = True, override XXXXXXXX'd out alias or NO PASS
+ and then modify its alias entry. 
 ************************************************************************/
 
 static BOOL mod_alsunixgrp_entry(LOCAL_GRP* als)
@@ -237,6 +233,35 @@ static BOOL mod_alsunixgrp_entry(LOCAL_GRP* als)
        return False;
 }
 
+/************************************************************************
+ Routine to search the grppasswd file for an entry matching the rid.
+ and then delete it.
+************************************************************************/
+
+static BOOL del_alsunixgrp_entry(uint32 rid)
+{
+       DEBUG(0, ("del_alsunixgrp_entry: NOT IMPLEMENTED\n"));
+       return False;
+}
+
+/************************************************************************
+ Routine to add a member to an entry to the grppasswd file.
+*************************************************************************/
+static BOOL add_alsunixgrp_member(uint32 rid, DOM_SID *member_sid)
+{
+       DEBUG(0, ("add_alsunixgrp_member: NOT IMPLEMENTED\n"));
+       return False;
+}
+
+/************************************************************************
+ Routine to delete a member from an entry to the grppasswd file.
+*************************************************************************/
+static BOOL del_alsunixgrp_member(uint32 rid, DOM_SID *member_sid)
+{
+       DEBUG(0, ("del_alsunixgrp_member: NOT IMPLEMENTED\n"));
+       return False;
+}
+
 
 static struct aliasdb_ops unix_ops =
 {
@@ -252,6 +277,10 @@ static struct aliasdb_ops unix_ops =
 
        add_alsunixgrp_entry,
        mod_alsunixgrp_entry,
+       del_alsunixgrp_entry,
+
+       add_alsunixgrp_member,
+       del_alsunixgrp_member,
 
        iterate_getuseraliasntnam      /* in aliasdb.c */
 };
index a840c396f9d3b42df523d72cbca2bd91be7a41e5..3b09b6225d8e3108da26f0ab0fa85196bac94e66 100644 (file)
@@ -365,6 +365,22 @@ BOOL mod_builtin_entry(LOCAL_GRP* blt)
        return bidb_ops->mod_alias_entry(blt);
 }
 
+/************************************************************************
+ Routine to add a member to an entry in the builtin database file.
+*************************************************************************/
+BOOL add_builtin_member(uint32 rid, DOM_SID *member_sid)
+{
+       return bidb_ops->add_alias_member(rid, member_sid);
+}
+
+/************************************************************************
+ Routine to delete a member from an entry in the builtindatabase file.
+*************************************************************************/
+BOOL del_builtin_member(uint32 rid, DOM_SID *member_sid)
+{
+       return bidb_ops->del_alias_member(rid, member_sid);
+}
+
 /************************************************************************
  Routine to search builtin database by name.
 *************************************************************************/
index 3fa28b63aeacab143a8d822ff20f001756f1d50e..c8ea767a77450c3515c5dffec3fe56559586c53d 100644 (file)
@@ -225,11 +225,7 @@ static BOOL add_bltunixgrp_entry(LOCAL_GRP *newblt)
 
 /************************************************************************
  Routine to search the bltpasswd file for an entry matching the builtinname.
- and then modify its builtin entry. We can't use the startbltpwent()/
- getbltpwent()/endbltpwent() interfaces here as we depend on looking
- in the actual file to decide how much room we have to write data.
- override = False, normal
- override = True, override XXXXXXXX'd out builtin or NO PASS
+ and then modify its builtin entry. 
 ************************************************************************/
 
 static BOOL mod_bltunixgrp_entry(LOCAL_GRP* blt)
@@ -238,6 +234,23 @@ static BOOL mod_bltunixgrp_entry(LOCAL_GRP* blt)
        return False;
 }
 
+/************************************************************************
+ Routine to add a member to an entry to the bltpasswd file.
+*************************************************************************/
+static BOOL add_bltunixgrp_member(uint32 rid, DOM_SID *member_sid)
+{
+       DEBUG(0, ("add_bltunixgrp_member: NOT IMPLEMENTED\n"));
+       return False;
+}
+
+/************************************************************************
+ Routine to delete a member from an entry to the bltpasswd file.
+*************************************************************************/
+static BOOL del_bltunixgrp_member(uint32 rid, DOM_SID *member_sid)
+{
+       DEBUG(0, ("del_bltunixgrp_member: NOT IMPLEMENTED\n"));
+       return False;
+}
 
 static struct aliasdb_ops unix_ops =
 {
@@ -253,6 +266,10 @@ static struct aliasdb_ops unix_ops =
 
        add_bltunixgrp_entry,
        mod_bltunixgrp_entry,
+       NULL, /* deliberately NULL: you can't delete builtin aliases */
+
+       add_bltunixgrp_member,
+       del_bltunixgrp_member,
 
        iterate_getuserbuiltinntnam      /* in builtindb.c */
 };
index 6bd6c34442f57e1f02d7a091f2ff3d369c944e9f..ed09560b3a8883e5ad05a6798332ecb7fe13d603 100644 (file)
@@ -343,15 +343,38 @@ DOMAIN_GRP *getgroupent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem)
 
 /************************************************************************
  Routine to add an entry to the group database file.
+ on entry, the entry is added by name.
+ on exit, the RID is expected to have been set.
 *************************************************************************/
 
 BOOL add_group_entry(DOMAIN_GRP *newgrp)
 {
-       return gpdb_ops->add_group_entry(newgrp);
+       BOOL ret;
+       if (newgrp->rid != 0xffffffff)
+       {
+               DEBUG(0,("add_group_entry - RID must be 0xffffffff, \
+database instance is responsible for allocating the RID, not you.\n"));
+               return False;
+       }
+       ret = gpdb_ops->add_group_entry(newgrp);
+       if (newgrp->rid == 0xffffffff)
+       {
+               DEBUG(0,("add_group_entry - RID has not been set by database\n"));
+               return False;
+       }
+       return ret;
+}
+
+/************************************************************************
+ Routine to delete group database entry matching by rid.
+************************************************************************/
+BOOL del_group_entry(uint32 rid)
+{
+       return gpdb_ops->del_group_entry(rid);
 }
 
 /************************************************************************
- Routine to search the group database file for an entry matching the groupname.
+ Routine to search group database file for entry matching by rid or groupname.
  and then replace the entry.
 ************************************************************************/
 
@@ -360,6 +383,22 @@ BOOL mod_group_entry(DOMAIN_GRP* grp)
        return gpdb_ops->mod_group_entry(grp);
 }
 
+/************************************************************************
+ Routine to add a member to an entry in the group database file.
+*************************************************************************/
+BOOL add_group_member(uint32 rid, uint32 member_rid)
+{
+       return gpdb_ops->add_group_member(rid, member_rid);
+}
+
+/************************************************************************
+ Routine to delete a member from an entry in the group database file.
+*************************************************************************/
+BOOL del_group_member(uint32 rid, uint32 member_rid)
+{
+       return gpdb_ops->del_group_member(rid, member_rid);
+}
+
 /************************************************************************
  Routine to search group database by name.
 *************************************************************************/
index e20ba6434c3c5be53ae1941521ee388822b4f26a..0e10b801d81819325beed14aedb39181797f01e3 100644 (file)
@@ -237,11 +237,7 @@ static BOOL add_grpfilegrp_entry(DOMAIN_GRP *newgrp)
 
 /************************************************************************
  Routine to search the grppasswd file for an entry matching the groupname.
- and then modify its group entry. We can't use the startgrppwent()/
- getgrppwent()/endgrppwent() interfaces here as we depend on looking
- in the actual file to decide how much room we have to write data.
- override = False, normal
- override = True, override XXXXXXXX'd out group or NO PASS
+ and then modify its group entry. 
 ************************************************************************/
 
 static BOOL mod_grpfilegrp_entry(DOMAIN_GRP* grp)
index 154e23338d9ce9dd10aa79aae41ff810d5494609..35f386cbf8bf4e6e8b31c7ac6431c4cfd34ca1a1 100644 (file)
@@ -224,12 +224,8 @@ static BOOL add_grpunixgrp_entry(DOMAIN_GRP *newgrp)
 }
 
 /************************************************************************
- Routine to search the grppasswd file for an entry matching the groupname.
- and then modify its group entry. We can't use the startgrppwent()/
- getgrppwent()/endgrppwent() interfaces here as we depend on looking
- in the actual file to decide how much room we have to write data.
- override = False, normal
- override = True, override XXXXXXXX'd out group or NO PASS
+ Routine to search database for entry matching the groupname and/or rid.
+ and then modify its group entry. 
 ************************************************************************/
 
 static BOOL mod_grpunixgrp_entry(DOMAIN_GRP* grp)
@@ -238,6 +234,34 @@ static BOOL mod_grpunixgrp_entry(DOMAIN_GRP* grp)
        return False;
 }
 
+/************************************************************************
+ Routine to search the grppasswd file for an entry matching the rid.
+ and then delete it.
+************************************************************************/
+
+static BOOL del_grpunixgrp_entry(uint32 rid)
+{
+       DEBUG(0, ("del_grpunixgrp_entry: NOT IMPLEMENTED\n"));
+       return False;
+}
+
+/************************************************************************
+ Routine to add a member to an entry to the grppasswd file.
+*************************************************************************/
+static BOOL add_grpunixgrp_member(uint32 rid, uint32 member_rid)
+{
+       DEBUG(0, ("add_grpunixgrp_member: NOT IMPLEMENTED\n"));
+       return False;
+}
+
+/************************************************************************
+ Routine to delete a member from an entry to the grppasswd file.
+*************************************************************************/
+static BOOL del_grpunixgrp_member(uint32 rid, uint32 member_rid)
+{
+       DEBUG(0, ("del_grpunixgrp_member: NOT IMPLEMENTED\n"));
+       return False;
+}
 
 static struct groupdb_ops unix_ops =
 {
@@ -253,6 +277,10 @@ static struct groupdb_ops unix_ops =
 
        add_grpunixgrp_entry,
        mod_grpunixgrp_entry,
+       del_grpunixgrp_entry,
+
+       add_grpunixgrp_member,
+       del_grpunixgrp_member,
 
        iterate_getusergroupsnam      /* in groupdb.c */
 };
index 647e8fdff99f3f078ce7181564adc0a25a085081..2e0f42e57538d94746973bd830e80546d6fee95a 100644 (file)
@@ -29,8 +29,11 @@ BOOL enumdomaliases(LOCAL_GRP **alss, int *num_alss);
 void *startaliasent(BOOL update);
 void endaliasent(void *vp);
 LOCAL_GRP *getaliasent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem);
-BOOL add_alias_entry(LOCAL_GRP *newals);
+BOOL add_alias_entry(LOCAL_GRP *newgrp);
 BOOL mod_alias_entry(LOCAL_GRP* als);
+BOOL del_alias_entry(uint32 rid);
+BOOL add_alias_member(uint32 rid, DOM_SID *member_sid);
+BOOL del_alias_member(uint32 rid, DOM_SID *member_sid);
 LOCAL_GRP *getaliasntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem);
 LOCAL_GRP *getaliasrid(uint32 alias_rid, LOCAL_GRP_MEMBER **mem, int *num_mem);
 LOCAL_GRP *getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem);
@@ -64,6 +67,8 @@ void endbuiltinent(void *vp);
 LOCAL_GRP *getbuiltinent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem);
 BOOL add_builtin_entry(LOCAL_GRP *newblt);
 BOOL mod_builtin_entry(LOCAL_GRP* blt);
+BOOL add_builtin_member(uint32 rid, DOM_SID *member_sid);
+BOOL del_builtin_member(uint32 rid, DOM_SID *member_sid);
 LOCAL_GRP *getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem);
 LOCAL_GRP *getbuiltinrid(uint32 builtin_rid, LOCAL_GRP_MEMBER **mem, int *num_mem);
 LOCAL_GRP *getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem);
@@ -92,7 +97,10 @@ void *startgroupent(BOOL update);
 void endgroupent(void *vp);
 DOMAIN_GRP *getgroupent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem);
 BOOL add_group_entry(DOMAIN_GRP *newgrp);
+BOOL del_group_entry(uint32 rid);
 BOOL mod_group_entry(DOMAIN_GRP* grp);
+BOOL add_group_member(uint32 rid, uint32 member_rid);
+BOOL del_group_member(uint32 rid, uint32 member_rid);
 DOMAIN_GRP *getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem);
 DOMAIN_GRP *getgrouprid(uint32 group_rid, DOMAIN_GRP_MEMBER **mem, int *num_mem);
 DOMAIN_GRP *getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem);
@@ -336,6 +344,14 @@ time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs);
 
 char *ufc_crypt(char *key,char *salt);
 
+/*The following definitions come from  lib/unix_sec_ctxt.c  */
+
+void init_sec_ctxt(void);
+BOOL become_unix_sec_ctxt(struct unix_sec_ctxt const *ctxt);
+BOOL unbecome_unix_sec_ctxt(void);
+void become_unix_root_sec_ctxt(void) ;
+void unbecome_unix_root_sec_ctxt(void);
+
 /*The following definitions come from  lib/username.c  */
 
 char *get_home_dir(char *user);
@@ -1501,7 +1517,7 @@ BOOL lsa_open_policy(struct cli_state *cli,
 BOOL lsa_lookup_names(struct cli_state *cli,
                        POLICY_HND *hnd,
                        int num_names,
-                       char **names,
+                       const char **names,
                        DOM_SID **sids,
                        int *num_sids);
 BOOL lsa_lookup_sids(struct cli_state *cli,
@@ -1591,10 +1607,16 @@ BOOL create_samr_domain_group(struct cli_state *cli,
 BOOL get_samr_query_usergroups(struct cli_state *cli, 
                                POLICY_HND *pol_open_domain, uint32 user_rid,
                                uint32 *num_groups, DOM_GID *gid);
+BOOL delete_samr_dom_group(struct cli_state *cli, 
+                               POLICY_HND *pol_open_domain,
+                               uint32 group_rid);
 BOOL get_samr_query_groupmem(struct cli_state *cli, 
                                POLICY_HND *pol_open_domain,
                                uint32 group_rid, uint32 *num_mem,
                                uint32 *rid, uint32 *attr);
+BOOL delete_samr_dom_alias(struct cli_state *cli, 
+                               POLICY_HND *pol_open_domain,
+                               uint32 alias_rid);
 BOOL get_samr_query_aliasmem(struct cli_state *cli, 
                                POLICY_HND *pol_open_domain,
                                uint32 alias_rid, uint32 *num_mem, DOM_SID2 *sid);
@@ -1633,10 +1655,15 @@ BOOL samr_open_user(struct cli_state *cli,
                                POLICY_HND *pol, uint32 unk_0, uint32 rid, 
                                POLICY_HND *user_pol);
 BOOL samr_open_alias(struct cli_state *cli, 
-                               POLICY_HND *domain_pol, uint32 rid,
+                               POLICY_HND *domain_pol,
+                               uint32 flags, uint32 rid,
                                POLICY_HND *alias_pol);
+BOOL samr_del_aliasmem(struct cli_state *cli, 
+                               POLICY_HND *alias_pol, DOM_SID *sid);
 BOOL samr_add_aliasmem(struct cli_state *cli, 
                                POLICY_HND *alias_pol, DOM_SID *sid);
+BOOL samr_delete_dom_alias(struct cli_state *cli, 
+                               POLICY_HND *alias_pol);
 BOOL samr_create_dom_alias(struct cli_state *cli, 
                                POLICY_HND *domain_pol, const char *acct_name,
                                POLICY_HND *alias_pol, uint32 *rid);
@@ -1646,8 +1673,11 @@ BOOL samr_open_group(struct cli_state *cli,
                                POLICY_HND *domain_pol,
                                uint32 flags, uint32 rid,
                                POLICY_HND *group_pol);
+BOOL samr_del_groupmem(struct cli_state *cli, 
+                               POLICY_HND *group_pol, uint32 rid);
 BOOL samr_add_groupmem(struct cli_state *cli, 
                                POLICY_HND *group_pol, uint32 rid);
+BOOL samr_delete_dom_group(struct cli_state *cli, POLICY_HND *group_pol);
 BOOL samr_create_dom_group(struct cli_state *cli, 
                                POLICY_HND *domain_pol, const char *acct_name,
                                POLICY_HND *group_pol, uint32 *rid);
@@ -1656,6 +1686,12 @@ BOOL samr_set_groupinfo(struct cli_state *cli,
 BOOL samr_open_domain(struct cli_state *cli, 
                                POLICY_HND *connect_pol, uint32 flags, DOM_SID *sid,
                                POLICY_HND *domain_pol);
+BOOL samr_query_lookup_names(struct cli_state *cli, 
+                               POLICY_HND *pol, uint32 flags,
+                               uint32 num_names, const char **names,
+                               uint32 *num_rids,
+                               uint32 rid[MAX_LOOKUP_SIDS],
+                               uint32 type[MAX_LOOKUP_SIDS]);
 BOOL samr_query_lookup_rids(struct cli_state *cli, 
                                POLICY_HND *pol, uint32 flags,
                                uint32 num_rids, uint32 *rids,
@@ -1745,7 +1781,7 @@ void make_q_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, POLICY_HND *hnd,
 void lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, int depth);
 void lsa_io_r_lookup_sids(char *desc,  LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, int depth);
 void make_q_lookup_names(LSA_Q_LOOKUP_NAMES *q_l, POLICY_HND *hnd,
-                               int num_names, char **names);
+                               int num_names, const char **names);
 void lsa_io_q_lookup_names(char *desc,  LSA_Q_LOOKUP_NAMES *q_r, prs_struct *ps, int depth);
 void lsa_io_r_lookup_names(char *desc,  LSA_R_LOOKUP_NAMES *r_r, prs_struct *ps, int depth);
 void make_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd);
@@ -1788,7 +1824,7 @@ void make_string2(STRING2 *str, char *buf, int len);
 void smb_io_string2(char *desc,  STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
 void make_unistr2(UNISTR2 *str, char *buf, int len);
 void smb_io_unistr2(char *desc,  UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
-void make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type);
+void make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx);
 void smb_io_dom_rid2(char *desc,  DOM_RID2 *rid2, prs_struct *ps, int depth);
 void make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type);
 void smb_io_dom_rid3(char *desc,  DOM_RID3 *rid3, prs_struct *ps, int depth);
@@ -2215,6 +2251,8 @@ void samr_io_r_delete_alias(char *desc,  SAMR_R_DELETE_DOM_ALIAS *r_u, prs_struc
 void make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u, POLICY_HND *hnd,
                                const char *acct_desc);
 void samr_io_q_create_dom_alias(char *desc,  SAMR_Q_CREATE_DOM_ALIAS *q_u, prs_struct *ps, int depth);
+void make_samr_r_create_dom_alias(SAMR_R_CREATE_DOM_ALIAS *r_u, POLICY_HND *pol,
+               uint32 rid, uint32 status);
 void samr_io_r_create_dom_alias(char *desc,  SAMR_R_CREATE_DOM_ALIAS *r_u, prs_struct *ps, int depth);
 void make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u, POLICY_HND *hnd,
                                DOM_SID *sid);
@@ -2234,6 +2272,9 @@ void samr_io_q_query_aliasmem(char *desc,  SAMR_Q_QUERY_ALIASMEM *q_u, prs_struc
 void make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM *r_u,
                uint32 num_sids, DOM_SID2 *sid, uint32 status);
 void samr_io_r_query_aliasmem(char *desc,  SAMR_R_QUERY_ALIASMEM *r_u, prs_struct *ps, int depth);
+void make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
+               POLICY_HND *pol, uint32 flags,
+               uint32 num_names, const char **name);
 void samr_io_q_lookup_names(char *desc,  SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth);
 void make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
                uint32 num_rids, uint32 *rid, uint8 *type, uint32 status);
@@ -2255,7 +2296,6 @@ void make_sam_user_info11(SAM_USER_INFO_11 *usr,
                                uint32 rid_user,
                                uint32 rid_group,
                                uint16 acct_ctrl);
-void sam_io_user_info11(char *desc,  SAM_USER_INFO_11 *usr, prs_struct *ps, int depth);
 void make_sam_user_info21(SAM_USER_INFO_21 *usr,
 
        NTTIME *logon_time,
@@ -2526,8 +2566,12 @@ void cmd_reg_get_key_sec(struct client_info *info);
 
 void cmd_sam_ntchange_pwd(struct client_info *info);
 void cmd_sam_test(struct client_info *info);
+void cmd_sam_del_aliasmem(struct client_info *info);
+void cmd_sam_delete_dom_alias(struct client_info *info);
 void cmd_sam_add_aliasmem(struct client_info *info);
 void cmd_sam_create_dom_alias(struct client_info *info);
+void cmd_sam_del_groupmem(struct client_info *info);
+void cmd_sam_delete_dom_group(struct client_info *info);
 void cmd_sam_add_groupmem(struct client_info *info);
 void cmd_sam_create_dom_group(struct client_info *info);
 void cmd_sam_enum_users(struct client_info *info);
index c35761ffeba70fb967ae01450fa916056843e5fe..a3090cefd6acfc37cf69217b9d757f562d773a7b 100644 (file)
@@ -993,24 +993,20 @@ typedef struct r_samr_query_useraliases_info
 
 
 /****************************************************************************
-SAMR_Q_LOOKUP_NAMES - do a conversion from SID to RID.
-
-the policy handle allocated by an "samr open secret" call is associated
-with a SID.  this policy handle is what is queried here, *not* the SID
-itself.  the response to the lookup rids is relative to this SID.
+SAMR_Q_LOOKUP_NAMES - do a conversion from Names to RIDs+types.
 *****************************************************************************/
 /* SAMR_Q_LOOKUP_NAMES */
 typedef struct q_samr_lookup_names_info
 {
     POLICY_HND pol;       /* policy handle */
 
-       uint32 num_rids1;      /* number of rids being looked up */
-       uint32 rid;            /* 0x0000 03e8 - RID of the server doing the query? */
+       uint32 num_names1;      /* number of names being looked up */
+       uint32 flags;           /* 0x0000 03e8 - unknown */
        uint32 ptr;            /* 0x0000 0000 - 32 bit unknown */
-       uint32 num_rids2;      /* number of rids being looked up */
+       uint32 num_names2;      /* number of names being looked up */
 
-       UNIHDR  hdr_user_name[MAX_LOOKUP_SIDS]; /* unicode account name header */
-       UNISTR2 uni_user_name[MAX_LOOKUP_SIDS]; /* unicode account name string */
+       UNIHDR  hdr_name[MAX_LOOKUP_SIDS]; /* unicode account name header */
+       UNISTR2 uni_name[MAX_LOOKUP_SIDS]; /* unicode account name string */
 
 } SAMR_Q_LOOKUP_NAMES;
 
@@ -1018,11 +1014,17 @@ typedef struct q_samr_lookup_names_info
 /* SAMR_R_LOOKUP_NAMES */
 typedef struct r_samr_lookup_names_info
 {
-       uint32 num_entries;
-       uint32 undoc_buffer; /* undocumented buffer pointer */
+       uint32 num_rids1;      /* number of aliases being looked up */
+       uint32 ptr_rids;       /* pointer to aliases */
+       uint32 num_rids2;      /* number of aliases being looked up */
 
-       uint32 num_entries2; 
-       DOM_RID3 dom_rid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
+       uint32 rid[MAX_LOOKUP_SIDS]; /* rids */
+
+       uint32 num_types1;      /* number of users in aliases being looked up */
+       uint32 ptr_types;       /* pointer to users in aliases */
+       uint32 num_types2;      /* number of users in aliases being looked up */
+
+       uint32 type[MAX_LOOKUP_SIDS]; /* SID_ENUM type */
 
        uint32 status; /* return code */
 
@@ -1040,7 +1042,7 @@ typedef struct q_samr_lookup_rids_info
        POLICY_HND pol;       /* policy handle */
 
        uint32 num_rids1;      /* number of rids being looked up */
-       uint32 flags;          /* 0x0000 03e8 - RID of the server doing the query? */
+       uint32 flags;          /* 0x0000 03e8 - unknown */
        uint32 ptr;            /* 0x0000 0000 - 32 bit unknown */
        uint32 num_rids2;      /* number of rids being looked up */
 
@@ -1227,17 +1229,17 @@ typedef struct r_samr_query_aliasmem_info
 } SAMR_R_QUERY_ALIASMEM;
 
 
-/* SAMR_Q_ADD_ALIASMEM - don't know! */
+/* SAMR_Q_ADD_ALIASMEM - add alias member */
 typedef struct q_samr_add_alias_mem_info
 {
        POLICY_HND alias_pol;       /* policy handle */
 
-       DOM_SID sid; /* member sid to be "something"ed to do with the alias */
+       DOM_SID sid; /* member sid to be added to the alias */
 
 } SAMR_Q_ADD_ALIASMEM;
 
 
-/* SAMR_R_ADD_ALIASMEM - probably an open */
+/* SAMR_R_ADD_ALIASMEM - add alias member */
 typedef struct r_samr_add_alias_mem_info
 {
        uint32 status;         /* return status */
index e4191f706d2bc396b95c47e13c6d9d2e3a4aaa7b..1ed4ea708909aae15ca9d59822d84353f0958ef9 100644 (file)
@@ -612,6 +612,34 @@ typedef struct connection_struct
 
 } connection_struct;
 
+struct unix_sec_ctxt
+{
+       uid_t uid;
+       gid_t gid;
+       int ngroups;
+       gid_t *groups;
+
+       char *name;
+};
+
+struct nt_sec_ctxt
+{
+       /* this should (will?) probably become a SEC_DESC */
+       DOM_SID user_sid;
+       DOM_SID group_sid;
+
+       char *name;
+       char *domain;
+};
+
+#if 0
+struct sec_ctxt
+{
+       struct unix_sec_ctxt unix;
+       struct nt_sec_ctxt   nt;
+};
+#endif
+
 struct current_user
 {
        connection_struct *conn;
@@ -898,6 +926,10 @@ struct groupdb_ops
         */
        BOOL (*add_group_entry)(DOMAIN_GRP *);
        BOOL (*mod_group_entry)(DOMAIN_GRP *);
+       BOOL (*del_group_entry)(uint32);
+
+       BOOL (*add_group_member)(uint32, uint32);
+       BOOL (*del_group_member)(uint32, uint32);
 
        /*
         * user group functions
@@ -937,6 +969,10 @@ struct aliasdb_ops
         */
        BOOL (*add_alias_entry)(LOCAL_GRP *);
        BOOL (*mod_alias_entry)(LOCAL_GRP *);
+       BOOL (*del_alias_entry)(uint32);
+
+       BOOL (*add_alias_member)(uint32, DOM_SID*);
+       BOOL (*del_alias_member)(uint32, DOM_SID*);
 
        /*
         * user alias functions
index 62c8f8a0cd80c181e00c5c25566a8c737c28affb..947de768b540a04208d7e7e368579a7ae72d2901 100644 (file)
@@ -193,37 +193,88 @@ static int make_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
 }
 
 /***************************************************************************
-make_reply_lookup_names
+make_lsa_rid2s
  ***************************************************************************/
-static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
-                               int num_entries,
-                               DOM_SID dom_sids [MAX_LOOKUP_SIDS],
-                               uint8   dom_types[MAX_LOOKUP_SIDS])
+static void make_lsa_rid2s(DOM_R_REF *ref,
+                               DOM_RID2 *rid2,
+                               int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS],
+                               uint32 *mapped_count)
 {
        int i;
+       int total = 0;
+       (*mapped_count) = 0;
 
-       r_l->num_entries = 0;
-       r_l->undoc_buffer = 0;
-       r_l->num_entries2 = 0;
-
-#if 0
-       r_l->num_entries = num_entries;
-       r_l->undoc_buffer = 1;
-       r_l->num_entries2 = num_entries;
-
-       SMB_ASSERT_ARRAY(r_l->dom_rid, num_entries);
+       SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
 
        for (i = 0; i < num_entries; i++)
        {
-               DOM_SID sid = dom_sids[i];
-               uint32 rid;
-               sid_split_rid(&sid, &rid);
-               make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid);
-               make_dom_rid2(&(r_l->dom_rid[i]), rid, dom_types[i]);
+               uint32 status = 0x0;
+               DOM_SID find_sid;
+               DOM_SID sid;
+               uint32 rid = 0xffffffff;
+               int dom_idx = -1;
+               fstring find_name;
+               char *dom_name = NULL;
+               uint8 sid_name_use = SID_NAME_UNKNOWN;
+
+               fstrcpy(find_name, unistr2_to_str(&name[i]));
+               dom_name = strdup(find_name);
+
+               if (map_domain_name_to_sid(&sid, &dom_name))
+               {
+                       sid_name_use = SID_NAME_DOMAIN;
+                       dom_idx = make_dom_ref(ref, dom_name, &find_sid);
+       }
+
+               if (lookup_name(find_name, &sid, &sid_name_use) == 0x0 &&
+                   sid_split_rid(&sid, &rid))
+               {
+                       if (map_domain_sid_to_name(&sid, find_name))
+                       {
+                               dom_idx = make_dom_ref(ref, find_name, &sid);
+                       }
+                       else
+                       {
+                               status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+                       }
+               }
+               else
+               {
+                       status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               }
+
+               if (status == 0x0)
+               {
+                       (*mapped_count)++;
+               }
+               else
+               {
+                       dom_idx = -1;
+                       rid = 0xffffffff;
+                       sid_name_use = SID_NAME_UNKNOWN;
+               }
+
+               make_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
+               total++;
+
+               if (dom_name != NULL)
+               {
+                       free(dom_name);
+               }
        }
+}
 
-       r_l->num_entries3 = num_entries;
-#endif
+/***************************************************************************
+make_reply_lookup_names
+ ***************************************************************************/
+static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
+                               DOM_R_REF *ref, DOM_RID2 *rid2,
+                               uint32 mapped_count, uint32 status)
+{
+       r_l->dom_ref      = ref;
+       r_l->dom_rid      = rid2;
+       r_l->mapped_count = mapped_count;
+       r_l->status       = status;
 }
 
 /***************************************************************************
@@ -340,18 +391,24 @@ static void lsa_reply_lookup_sids(prs_struct *rdata,
 lsa_reply_lookup_names
  ***************************************************************************/
 static void lsa_reply_lookup_names(prs_struct *rdata,
-                               int num_entries,
-                               DOM_SID dom_sids [MAX_LOOKUP_SIDS],
-                               uint8   dom_types[MAX_LOOKUP_SIDS])
+                               UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
 {
        LSA_R_LOOKUP_NAMES r_l;
+       DOM_R_REF ref;
+       DOM_RID2 rids[MAX_LOOKUP_SIDS];
+       uint32 mapped_count = 0;
 
        ZERO_STRUCT(r_l);
+       ZERO_STRUCT(ref);
+       ZERO_STRUCT(rids);
 
        /* set up the LSA Lookup RIDs response */
-       make_reply_lookup_names(&r_l, num_entries, dom_sids, dom_types);
+       make_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
+       make_reply_lookup_names(&r_l, &ref, rids, mapped_count, 0x0);
 
-       r_l.status = 0x0;
+       r_l.num_entries  = num_entries;
+       r_l.undoc_buffer = 1;
+       r_l.num_entries2 = num_entries;
 
        /* store the response in the SMB stream */
        lsa_io_r_lookup_names("", &r_l, rdata, 0);
@@ -476,36 +533,16 @@ api_lsa_lookup_names
 static void api_lsa_lookup_names( uint16 vuid, prs_struct *data,
                                   prs_struct *rdata )
 {
-       int i;
        LSA_Q_LOOKUP_NAMES q_l;
-       DOM_SID dom_sids [MAX_LOOKUP_SIDS];
-       uint8   dom_types[MAX_LOOKUP_SIDS];
-
        ZERO_STRUCT(q_l);
-       ZERO_ARRAY(dom_sids);   
 
        /* grab the info class and policy handle */
        lsa_io_q_lookup_names("", &q_l, data, 0);
 
        SMB_ASSERT_ARRAY(q_l.uni_name, q_l.num_entries);
 
-       /* convert received RIDs to strings, so we can do them. */
-       for (i = 0; i < q_l.num_entries; i++)
-       {
-               fstring name;
-               fstrcpy(name, unistr2_to_str(&q_l.uni_name[i]));
-
-               if (!lookup_name(name, &dom_sids[i], &dom_types[i]))
-               {
-                       dom_types[i] = SID_NAME_UNKNOWN;
-               }
-       }
-
        /* construct reply.  return status is always 0x0 */
-       lsa_reply_lookup_names(rdata,
-                              q_l.num_entries,
-                             dom_sids, /* text-converted SIDs */
-                             dom_types); /* SID_NAME_USE types */
+       lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
 }
 
 /***************************************************************************
index 0516cee96d334b2b83a2891bce031b3d9ca8c017..f0c9bdfe16390a499e7c37a4a0a5b0ed0799375f 100644 (file)
@@ -104,7 +104,7 @@ do a LSA Lookup Names
 BOOL lsa_lookup_names(struct cli_state *cli,
                        POLICY_HND *hnd,
                        int num_names,
-                       char **names,
+                       const char **names,
                        DOM_SID **sids,
                        int *num_sids)
 {
@@ -197,7 +197,10 @@ BOOL lsa_lookup_names(struct cli_state *cli,
                                if (dom_idx != 0xffffffff)
                                {
                                        sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid);
+                                       if (dom_rid != 0xffffffff)
+                                       {
                                        sid_append_rid(sid, dom_rid);
+                                       }
                                }
                                else
                                {
index 4fc1c3f5a098fb94dfe002e00159454e3436a732..e950269ec31a6f8bdadaa55179d22dff448a5ccc 100644 (file)
@@ -149,6 +149,38 @@ BOOL get_samr_query_usergroups(struct cli_state *cli,
        return samr_close(cli, &pol_open_user) && ret;
 }
 
+/****************************************************************************
+do a SAMR delete group 
+****************************************************************************/
+BOOL delete_samr_dom_group(struct cli_state *cli, 
+                               POLICY_HND *pol_open_domain,
+                               uint32 group_rid)
+{
+       POLICY_HND pol_open_group;
+
+       if (pol_open_domain == NULL) return False;
+
+       /* send open domain (on group rid) */
+       if (!samr_open_group(cli, pol_open_domain,
+                               0x00000010, group_rid,
+                               &pol_open_group))
+       {
+               return False;
+       }
+
+       /* send group delete */
+       if (!samr_delete_dom_group(cli, &pol_open_group))
+                               
+       {
+               DEBUG(5,("delete_samr_dom_group: error in delete domain group\n"));
+               samr_close(cli, &pol_open_group);
+               return False;
+       }
+
+       return True;
+}
+
+
 /****************************************************************************
 do a SAMR query group members 
 ****************************************************************************/
@@ -181,6 +213,37 @@ BOOL get_samr_query_groupmem(struct cli_state *cli,
        return samr_close(cli, &pol_open_group) && ret;
 }
 
+/****************************************************************************
+do a SAMR delete alias 
+****************************************************************************/
+BOOL delete_samr_dom_alias(struct cli_state *cli, 
+                               POLICY_HND *pol_open_domain,
+                               uint32 alias_rid)
+{
+       POLICY_HND pol_open_alias;
+
+       if (pol_open_domain == NULL) return False;
+
+       /* send open domain (on alias rid) */
+       if (!samr_open_alias(cli, pol_open_domain,
+                               0x000f001f, alias_rid, &pol_open_alias))
+       {
+               return False;
+       }
+
+       /* send alias delete */
+       if (!samr_delete_dom_alias(cli, &pol_open_alias))
+                               
+       {
+               DEBUG(5,("delete_samr_dom_alias: error in delete domain alias\n"));
+               samr_close(cli, &pol_open_alias);
+               return False;
+       }
+
+       return True;
+}
+
+
 /****************************************************************************
 do a SAMR query alias members 
 ****************************************************************************/
@@ -195,7 +258,7 @@ BOOL get_samr_query_aliasmem(struct cli_state *cli,
 
        /* send open domain (on alias sid) */
        if (!samr_open_alias(cli, pol_open_domain,
-                               alias_rid,
+                               0x000f001f, alias_rid,
                                &pol_open_alias))
        {
                return False;
@@ -842,7 +905,8 @@ BOOL samr_open_user(struct cli_state *cli,
 do a SAMR Open Alias
 ****************************************************************************/
 BOOL samr_open_alias(struct cli_state *cli, 
-                               POLICY_HND *domain_pol, uint32 rid,
+                               POLICY_HND *domain_pol,
+                               uint32 flags, uint32 rid,
                                POLICY_HND *alias_pol)
 {
        prs_struct data;
@@ -861,7 +925,7 @@ BOOL samr_open_alias(struct cli_state *cli,
        prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
 
        /* store the parameters */
-       make_samr_q_open_alias(&q_o, domain_pol, 0x000f001f, rid);
+       make_samr_q_open_alias(&q_o, domain_pol, flags, rid);
 
        /* turn parameters into data stream */
        samr_io_q_open_alias("", &q_o,  &data, 0);
@@ -895,6 +959,61 @@ BOOL samr_open_alias(struct cli_state *cli,
        return valid_pol;
 }
 
+/****************************************************************************
+do a SAMR Delete Alias Member
+****************************************************************************/
+BOOL samr_del_aliasmem(struct cli_state *cli, 
+                               POLICY_HND *alias_pol, DOM_SID *sid)
+{
+       prs_struct data;
+       prs_struct rdata;
+
+       SAMR_Q_DEL_ALIASMEM q_o;
+       BOOL valid_pol = False;
+
+       if (alias_pol == NULL || sid == NULL) return False;
+
+       /* create and send a MSRPC command with api SAMR_DEL_ALIASMEM */
+
+       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+
+       DEBUG(4,("SAMR Delete Alias Member.\n"));
+
+       /* store the parameters */
+       make_samr_q_del_aliasmem(&q_o, alias_pol, sid);
+
+       /* turn parameters into data stream */
+       samr_io_q_del_aliasmem("", &q_o,  &data, 0);
+
+       /* send the data on \PIPE\ */
+       if (rpc_api_pipe_req(cli, SAMR_DEL_ALIASMEM, &data, &rdata))
+       {
+               SAMR_R_DEL_ALIASMEM r_o;
+               BOOL p;
+
+               samr_io_r_del_aliasmem("", &r_o, &rdata, 0);
+               p = rdata.offset != 0;
+
+               if (p && r_o.status != 0)
+               {
+                       /* report error code */
+                       DEBUG(0,("SAMR_R_DEL_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
+                       p = False;
+               }
+
+               if (p)
+               {
+                       valid_pol = True;
+               }
+       }
+
+       prs_mem_free(&data   );
+       prs_mem_free(&rdata  );
+
+       return valid_pol;
+}
+
 /****************************************************************************
 do a SAMR Add Alias Member
 ****************************************************************************/
@@ -950,6 +1069,61 @@ BOOL samr_add_aliasmem(struct cli_state *cli,
        return valid_pol;
 }
 
+/****************************************************************************
+do a SAMR Delete Domain Alias
+****************************************************************************/
+BOOL samr_delete_dom_alias(struct cli_state *cli, 
+                               POLICY_HND *alias_pol)
+{
+       prs_struct data;
+       prs_struct rdata;
+
+       SAMR_Q_DELETE_DOM_ALIAS q_o;
+       BOOL valid_pol = False;
+
+       if (alias_pol == NULL) return False;
+
+       /* delete and send a MSRPC command with api SAMR_DELETE_DOM_ALIAS */
+
+       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+
+       DEBUG(4,("SAMR Delete Domain Alias.\n"));
+
+       /* store the parameters */
+       make_samr_q_delete_dom_alias(&q_o, alias_pol);
+
+       /* turn parameters into data stream */
+       samr_io_q_delete_dom_alias("", &q_o,  &data, 0);
+
+       /* send the data on \PIPE\ */
+       if (rpc_api_pipe_req(cli, SAMR_DELETE_DOM_ALIAS, &data, &rdata))
+       {
+               SAMR_R_DELETE_DOM_ALIAS r_o;
+               BOOL p;
+
+               samr_io_r_delete_dom_alias("", &r_o, &rdata, 0);
+               p = rdata.offset != 0;
+
+               if (p && r_o.status != 0)
+               {
+                       /* report error code */
+                       DEBUG(0,("SAMR_R_DELETE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
+                       p = False;
+               }
+
+               if (p)
+               {
+                       valid_pol = True;
+               }
+       }
+
+       prs_mem_free(&data   );
+       prs_mem_free(&rdata  );
+
+       return valid_pol;
+}
+
 /****************************************************************************
 do a SAMR Create Domain Alias
 ****************************************************************************/
@@ -1121,6 +1295,61 @@ BOOL samr_open_group(struct cli_state *cli,
        return valid_pol;
 }
 
+/****************************************************************************
+do a SAMR Delete Group Member
+****************************************************************************/
+BOOL samr_del_groupmem(struct cli_state *cli, 
+                               POLICY_HND *group_pol, uint32 rid)
+{
+       prs_struct data;
+       prs_struct rdata;
+
+       SAMR_Q_DEL_GROUPMEM q_o;
+       BOOL valid_pol = False;
+
+       if (group_pol == NULL) return False;
+
+       /* create and send a MSRPC command with api SAMR_DEL_GROUPMEM */
+
+       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+
+       DEBUG(4,("SAMR Delete Group Member.\n"));
+
+       /* store the parameters */
+       make_samr_q_del_groupmem(&q_o, group_pol, rid);
+
+       /* turn parameters into data stream */
+       samr_io_q_del_groupmem("", &q_o,  &data, 0);
+
+       /* send the data on \PIPE\ */
+       if (rpc_api_pipe_req(cli, SAMR_DEL_GROUPMEM, &data, &rdata))
+       {
+               SAMR_R_DEL_GROUPMEM r_o;
+               BOOL p;
+
+               samr_io_r_del_groupmem("", &r_o, &rdata, 0);
+               p = rdata.offset != 0;
+
+               if (p && r_o.status != 0)
+               {
+                       /* report error code */
+                       DEBUG(0,("SAMR_R_DEL_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
+                       p = False;
+               }
+
+               if (p)
+               {
+                       valid_pol = True;
+               }
+       }
+
+       prs_mem_free(&data   );
+       prs_mem_free(&rdata  );
+
+       return valid_pol;
+}
+
 /****************************************************************************
 do a SAMR Add Group Member
 ****************************************************************************/
@@ -1176,6 +1405,60 @@ BOOL samr_add_groupmem(struct cli_state *cli,
        return valid_pol;
 }
 
+/****************************************************************************
+do a SAMR Delete Domain Group
+****************************************************************************/
+BOOL samr_delete_dom_group(struct cli_state *cli, POLICY_HND *group_pol)
+{
+       prs_struct data;
+       prs_struct rdata;
+
+       SAMR_Q_DELETE_DOM_GROUP q_o;
+       BOOL valid_pol = False;
+
+       if (group_pol == NULL) return False;
+
+       /* delete and send a MSRPC command with api SAMR_DELETE_DOM_GROUP */
+
+       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+
+       DEBUG(4,("SAMR Delete Domain Group.\n"));
+
+       /* store the parameters */
+       make_samr_q_delete_dom_group(&q_o, group_pol);
+
+       /* turn parameters into data stream */
+       samr_io_q_delete_dom_group("", &q_o,  &data, 0);
+
+       /* send the data on \PIPE\ */
+       if (rpc_api_pipe_req(cli, SAMR_DELETE_DOM_GROUP, &data, &rdata))
+       {
+               SAMR_R_DELETE_DOM_GROUP r_o;
+               BOOL p;
+
+               samr_io_r_delete_dom_group("", &r_o, &rdata, 0);
+               p = rdata.offset != 0;
+
+               if (p && r_o.status != 0)
+               {
+                       /* report error code */
+                       DEBUG(0,("SAMR_R_DELETE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
+                       p = False;
+               }
+
+               if (p)
+               {
+                       valid_pol = True;
+               }
+       }
+
+       prs_mem_free(&data   );
+       prs_mem_free(&rdata  );
+
+       return valid_pol;
+}
+
 /****************************************************************************
 do a SAMR Create Domain Group
 ****************************************************************************/
@@ -1348,6 +1631,91 @@ BOOL samr_open_domain(struct cli_state *cli,
        return valid_pol;
 }
 
+/****************************************************************************
+do a SAMR Query Lookup Names
+****************************************************************************/
+BOOL samr_query_lookup_names(struct cli_state *cli, 
+                               POLICY_HND *pol, uint32 flags,
+                               uint32 num_names, const char **names,
+                               uint32 *num_rids,
+                               uint32 rid[MAX_LOOKUP_SIDS],
+                               uint32 type[MAX_LOOKUP_SIDS])
+{
+       prs_struct data;
+       prs_struct rdata;
+
+       SAMR_Q_LOOKUP_NAMES q_o;
+       BOOL valid_query = False;
+
+       if (pol == NULL || flags == 0 || num_names == 0 || names == NULL ||
+           num_rids == NULL || rid == NULL || type == NULL ) return False;
+
+       /* create and send a MSRPC command with api SAMR_LOOKUP_NAMES */
+
+       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+
+       DEBUG(4,("SAMR Query Lookup NAMES.\n"));
+
+       /* store the parameters */
+       make_samr_q_lookup_names(&q_o, pol, flags, num_names, names);
+
+       /* turn parameters into data stream */
+       samr_io_q_lookup_names("", &q_o, &data, 0);
+
+       /* send the data on \PIPE\ */
+       if (rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &data, &rdata))
+       {
+               SAMR_R_LOOKUP_NAMES r_o;
+               BOOL p;
+
+               samr_io_r_lookup_names("", &r_o, &rdata, 0);
+               p = rdata.offset != 0;
+               
+               if (p && r_o.status != 0)
+               {
+                       /* report error code */
+                       DEBUG(0,("SAMR_R_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_o.status)));
+                       p = False;
+               }
+
+               if (p)
+               {
+                       if (r_o.ptr_rids != 0 && r_o.ptr_types != 0 &&
+                           r_o.num_types1 == r_o.num_rids1)
+                       {
+                               int i;
+
+                               valid_query = True;
+                               *num_rids = r_o.num_rids1;
+
+                               for (i = 0; i < r_o.num_rids1; i++)
+                               {
+                                       rid[i] = r_o.rid[i];
+                               }
+                               for (i = 0; i < r_o.num_types1; i++)
+                               {
+                                       type[i] = r_o.type[i];
+                               }
+                       }
+                       else if (r_o.ptr_rids == 0 && r_o.ptr_types == 0)
+                       {
+                               valid_query = True;
+                               *num_rids = 0;
+                       }
+                       else
+                       {
+                               p = False;
+                       }
+               }
+       }
+
+       prs_mem_free(&data   );
+       prs_mem_free(&rdata  );
+
+       return valid_query;
+}
+
 /****************************************************************************
 do a SAMR Query Lookup RIDS
 ****************************************************************************/
index 9781e3cfabba729f908c1c02269d82c05e482176..0b294b84f33799fc6451b193a9488562acf352e8 100644 (file)
@@ -77,7 +77,7 @@ static void lsa_io_dom_r_ref(char *desc,  DOM_R_REF *r_r, prs_struct *ps, int de
        prs_uint32("max_entries   ", ps, depth, &(r_r->max_entries   )); /* 32 - max number of entries */
        prs_uint32("num_ref_doms_2", ps, depth, &(r_r->num_ref_doms_2)); /* 4 - num referenced domains? */
 
-       SMB_ASSERT_ARRAY(r_r->hdr_ref_dom, r_r->num_ref_doms_1-1);
+       SMB_ASSERT_ARRAY(r_r->hdr_ref_dom, r_r->num_ref_doms_1);
        SMB_ASSERT_ARRAY(r_r->ref_dom, r_r->num_ref_doms_2);
 
        for (i = 0; i < r_r->num_ref_doms_1; i++)
@@ -668,7 +668,7 @@ void lsa_io_r_lookup_sids(char *desc,  LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, i
 makes a structure.
 ********************************************************************/
 void make_q_lookup_names(LSA_Q_LOOKUP_NAMES *q_l, POLICY_HND *hnd,
-                               int num_names, char **names)
+                               int num_names, const char **names)
 {
        int i;
        if (q_l == NULL) return;
index 18c5f23ce37a3e7addd73a3cdeca3cc1e6e2884c..fdc67d09059e327a747186cf8389e49bd5a90134 100644 (file)
@@ -617,11 +617,11 @@ void smb_io_unistr2(char *desc,  UNISTR2 *uni2, uint32 buffer, prs_struct *ps, i
 /*******************************************************************
 creates a DOM_RID2 structure.
 ********************************************************************/
-void make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type)
+void make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
 {
        rid2->type    = type;
        rid2->rid     = rid;
-       rid2->rid_idx = 0;
+       rid2->rid_idx = idx;
 }
 
 /*******************************************************************
index 5460d4773b2c4675ceb0fd671f114205f3bdb861..bfcc811aeaf2e98386b85e27a5894d54cb546044 100644 (file)
@@ -2912,6 +2912,22 @@ void samr_io_q_create_dom_alias(char *desc,  SAMR_Q_CREATE_DOM_ALIAS *q_u, prs_s
        prs_uint16("unknown_2", ps, depth, &(q_u->unknown_2));
 }
 
+/*******************************************************************
+makes a SAMR_R_CREATE_DOM_ALIAS structure.
+********************************************************************/
+void make_samr_r_create_dom_alias(SAMR_R_CREATE_DOM_ALIAS *r_u, POLICY_HND *pol,
+               uint32 rid, uint32 status)
+{
+       if (r_u == NULL) return;
+
+       DEBUG(5,("make_samr_r_create_dom_alias\n"));
+
+       memcpy(&(r_u->alias_pol), pol, sizeof(*pol));
+       r_u->rid    = rid   ;
+       r_u->status = status;
+}
+
+
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
@@ -3180,6 +3196,33 @@ void samr_io_r_query_aliasmem(char *desc,  SAMR_R_QUERY_ALIASMEM *r_u, prs_struc
        prs_uint32("status", ps, depth, &(r_u->status));
 }
 
+/*******************************************************************
+makes a SAMR_Q_LOOKUP_NAMES structure.
+********************************************************************/
+void make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
+               POLICY_HND *pol, uint32 flags,
+               uint32 num_names, const char **name)
+{
+       int i;
+       if (q_u == NULL) return;
+
+       DEBUG(5,("make_samr_q_lookup_names\n"));
+
+       memcpy(&(q_u->pol), pol, sizeof(*pol));
+
+       q_u->num_names1 = num_names;
+       q_u->flags     = flags;
+       q_u->ptr       = 0;
+       q_u->num_names2 = num_names;
+
+       for (i = 0; i < num_names; i++)
+       {
+               int len_name = name[i] != NULL ? strlen(name[i]) : 0;
+               make_uni_hdr(&(q_u->hdr_name[i]), len_name, len_name, name[i] != NULL);  /* unicode header for user_name */
+               make_unistr2(&(q_u->uni_name[i]), name[i], len_name);  /* unicode string for machine account */
+       }
+}
+
 
 /*******************************************************************
 reads or writes a structure.
@@ -3198,22 +3241,22 @@ void samr_io_q_lookup_names(char *desc,  SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *p
        smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
        prs_align(ps);
 
-       prs_uint32("num_rids1", ps, depth, &(q_u->num_rids1));
-       prs_uint32("rid      ", ps, depth, &(q_u->rid      ));
+       prs_uint32("num_names1", ps, depth, &(q_u->num_names1));
+       prs_uint32("flags     ", ps, depth, &(q_u->flags     ));
        prs_uint32("ptr      ", ps, depth, &(q_u->ptr      ));
-       prs_uint32("num_rids2", ps, depth, &(q_u->num_rids2));
+       prs_uint32("num_names2", ps, depth, &(q_u->num_names2));
 
-       SMB_ASSERT_ARRAY(q_u->hdr_user_name, q_u->num_rids2);
+       SMB_ASSERT_ARRAY(q_u->hdr_name, q_u->num_names2);
 
-       for (i = 0; i < q_u->num_rids2; i++)
+       for (i = 0; i < q_u->num_names2; i++)
        {
                prs_grow(ps);
-               smb_io_unihdr ("", &(q_u->hdr_user_name[i]), ps, depth); 
+               smb_io_unihdr ("", &(q_u->hdr_name[i]), ps, depth); 
        }
-       for (i = 0; i < q_u->num_rids2; i++)
+       for (i = 0; i < q_u->num_names2; i++)
        {
                prs_grow(ps);
-               smb_io_unistr2("", &(q_u->uni_user_name[i]), q_u->hdr_user_name[i].buffer, ps, depth); 
+               smb_io_unistr2("", &(q_u->uni_name[i]), q_u->hdr_name[i].buffer, ps, depth); 
        }
 
        prs_align(ps);
@@ -3233,22 +3276,31 @@ void make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
 
        if (status == 0x0)
        {
-               r_u->num_entries  = num_rids;
-               r_u->undoc_buffer = 1;
-               r_u->num_entries2 = num_rids;
+               r_u->num_types1 = num_rids;
+               r_u->ptr_types  = 1;
+               r_u->num_types2 = num_rids;
 
-               SMB_ASSERT_ARRAY(r_u->dom_rid, num_rids);
+               r_u->num_rids1 = num_rids;
+               r_u->ptr_rids  = 1;
+               r_u->num_rids2 = num_rids;
+
+               SMB_ASSERT_ARRAY(r_u->rid, num_rids);
 
                for (i = 0; i < num_rids; i++)
                {
-                       make_dom_rid3(&(r_u->dom_rid[i]), rid[i], type[i]);
+                       r_u->rid [i] = rid [i];
+                       r_u->type[i] = type[i];
                }
        }
        else
        {
-               r_u->num_entries  = 0;
-               r_u->undoc_buffer = 0;
-               r_u->num_entries2 = 0;
+               r_u->num_types1 = 0;
+               r_u->ptr_types  = 0;
+               r_u->num_types2 = 0;
+
+               r_u->num_rids1 = 0;
+               r_u->ptr_rids  = 0;
+               r_u->num_rids2 = 0;
        }
 
        r_u->status = status;
@@ -3260,6 +3312,8 @@ reads or writes a structure.
 void samr_io_r_lookup_names(char *desc,  SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth)
 {
        int i;
+       fstring tmp;
+
        if (r_u == NULL) return;
 
        prs_debug(ps, depth, desc, "samr_io_r_lookup_names");
@@ -3267,20 +3321,32 @@ void samr_io_r_lookup_names(char *desc,  SAMR_R_LOOKUP_NAMES *r_u, prs_struct *p
 
        prs_align(ps);
 
-       prs_uint32("num_entries ", ps, depth, &(r_u->num_entries ));
-       prs_uint32("undoc_buffer", ps, depth, &(r_u->undoc_buffer));
-       prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+       prs_uint32("num_rids1", ps, depth, &(r_u->num_rids1));
+       prs_uint32("ptr_rids ", ps, depth, &(r_u->ptr_rids ));
+       prs_uint32("num_rids2", ps, depth, &(r_u->num_rids2));
 
-       if (r_u->num_entries != 0)
+       if (r_u->ptr_rids != 0 && r_u->num_rids1 != 0)
        {
-               SMB_ASSERT_ARRAY(r_u->dom_rid, r_u->num_entries2);
-
-               for (i = 0; i < r_u->num_entries2; i++)
+               for (i = 0; i < r_u->num_rids2; i++)
                {
                        prs_grow(ps);
-                       smb_io_dom_rid3("", &(r_u->dom_rid[i]), ps, depth);
+                       slprintf(tmp, sizeof(tmp) - 1, "rid[%02d]  ", i);
+                       prs_uint32(tmp, ps, depth, &(r_u->rid[i]));
+               }
        }
 
+       prs_uint32("num_types1", ps, depth, &(r_u->num_types1));
+       prs_uint32("ptr_types ", ps, depth, &(r_u->ptr_types ));
+       prs_uint32("num_types2", ps, depth, &(r_u->num_types2));
+
+       if (r_u->ptr_types != 0 && r_u->num_types1 != 0)
+       {
+               for (i = 0; i < r_u->num_types2; i++)
+               {
+                       prs_grow(ps);
+                       slprintf(tmp, sizeof(tmp) - 1, "type[%02d]  ", i);
+                       prs_uint32(tmp, ps, depth, &(r_u->type[i]));
+               }
        }
 
        prs_uint32("status", ps, depth, &(r_u->status));
@@ -3476,8 +3542,6 @@ void make_sam_user_info11(SAM_USER_INFO_11 *usr,
        usr->padding_8    = 0;            /* 0 - padding 4 bytes */
        
        make_unistr2(&(usr->uni_mach_acct), mach_acct, len_mach_acct);  /* unicode string for machine account */
-
-       bzero(usr->padding_9, sizeof(usr->padding_9)); /* 0 - padding 48 bytes */
 }
 
 /*******************************************************************
@@ -3526,6 +3590,7 @@ void sam_io_user_info11(char *desc,  SAM_USER_INFO_11 *usr, prs_struct *ps, int
 
        prs_uint8s (False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9));
 }
+
 /*************************************************************************
  make_sam_user_info21
 
index c97a4cd0b9973c4a2ead1ea77ad455fc321023aa..70183636d154443786af4a352c7df1c30ad5c18a 100644 (file)
@@ -572,14 +572,8 @@ uint32 lookup_name(char *name, DOM_SID *sid, uint8 *type)
        
        split_domain_name(name, domain, user);
 
-       if (!strequal(domain, global_sam_name))
-       {
-               DEBUG(0,("lookup_name: remote domain %s not supported\n", domain));
-               return status;
-       }
-
-       status = (status != 0x0) ? lookup_user_name    (name, domain, sid, type) : status;
-       status = (status != 0x0) ? lookup_grp_name     (name, domain, sid, type) : status;
+       status = (status != 0x0) ? lookup_user_name    (user, domain, sid, type) : status;
+       status = (status != 0x0) ? lookup_grp_name     (user, domain, sid, type) : status;
 #if 0
        status = (status != 0x0) ? lookup_domain_name  (domain, sid, type) : status;
 #endif
index 62c8f8a0cd80c181e00c5c25566a8c737c28affb..947de768b540a04208d7e7e368579a7ae72d2901 100644 (file)
@@ -193,37 +193,88 @@ static int make_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
 }
 
 /***************************************************************************
-make_reply_lookup_names
+make_lsa_rid2s
  ***************************************************************************/
-static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
-                               int num_entries,
-                               DOM_SID dom_sids [MAX_LOOKUP_SIDS],
-                               uint8   dom_types[MAX_LOOKUP_SIDS])
+static void make_lsa_rid2s(DOM_R_REF *ref,
+                               DOM_RID2 *rid2,
+                               int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS],
+                               uint32 *mapped_count)
 {
        int i;
+       int total = 0;
+       (*mapped_count) = 0;
 
-       r_l->num_entries = 0;
-       r_l->undoc_buffer = 0;
-       r_l->num_entries2 = 0;
-
-#if 0
-       r_l->num_entries = num_entries;
-       r_l->undoc_buffer = 1;
-       r_l->num_entries2 = num_entries;
-
-       SMB_ASSERT_ARRAY(r_l->dom_rid, num_entries);
+       SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
 
        for (i = 0; i < num_entries; i++)
        {
-               DOM_SID sid = dom_sids[i];
-               uint32 rid;
-               sid_split_rid(&sid, &rid);
-               make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid);
-               make_dom_rid2(&(r_l->dom_rid[i]), rid, dom_types[i]);
+               uint32 status = 0x0;
+               DOM_SID find_sid;
+               DOM_SID sid;
+               uint32 rid = 0xffffffff;
+               int dom_idx = -1;
+               fstring find_name;
+               char *dom_name = NULL;
+               uint8 sid_name_use = SID_NAME_UNKNOWN;
+
+               fstrcpy(find_name, unistr2_to_str(&name[i]));
+               dom_name = strdup(find_name);
+
+               if (map_domain_name_to_sid(&sid, &dom_name))
+               {
+                       sid_name_use = SID_NAME_DOMAIN;
+                       dom_idx = make_dom_ref(ref, dom_name, &find_sid);
+       }
+
+               if (lookup_name(find_name, &sid, &sid_name_use) == 0x0 &&
+                   sid_split_rid(&sid, &rid))
+               {
+                       if (map_domain_sid_to_name(&sid, find_name))
+                       {
+                               dom_idx = make_dom_ref(ref, find_name, &sid);
+                       }
+                       else
+                       {
+                               status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+                       }
+               }
+               else
+               {
+                       status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               }
+
+               if (status == 0x0)
+               {
+                       (*mapped_count)++;
+               }
+               else
+               {
+                       dom_idx = -1;
+                       rid = 0xffffffff;
+                       sid_name_use = SID_NAME_UNKNOWN;
+               }
+
+               make_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
+               total++;
+
+               if (dom_name != NULL)
+               {
+                       free(dom_name);
+               }
        }
+}
 
-       r_l->num_entries3 = num_entries;
-#endif
+/***************************************************************************
+make_reply_lookup_names
+ ***************************************************************************/
+static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
+                               DOM_R_REF *ref, DOM_RID2 *rid2,
+                               uint32 mapped_count, uint32 status)
+{
+       r_l->dom_ref      = ref;
+       r_l->dom_rid      = rid2;
+       r_l->mapped_count = mapped_count;
+       r_l->status       = status;
 }
 
 /***************************************************************************
@@ -340,18 +391,24 @@ static void lsa_reply_lookup_sids(prs_struct *rdata,
 lsa_reply_lookup_names
  ***************************************************************************/
 static void lsa_reply_lookup_names(prs_struct *rdata,
-                               int num_entries,
-                               DOM_SID dom_sids [MAX_LOOKUP_SIDS],
-                               uint8   dom_types[MAX_LOOKUP_SIDS])
+                               UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
 {
        LSA_R_LOOKUP_NAMES r_l;
+       DOM_R_REF ref;
+       DOM_RID2 rids[MAX_LOOKUP_SIDS];
+       uint32 mapped_count = 0;
 
        ZERO_STRUCT(r_l);
+       ZERO_STRUCT(ref);
+       ZERO_STRUCT(rids);
 
        /* set up the LSA Lookup RIDs response */
-       make_reply_lookup_names(&r_l, num_entries, dom_sids, dom_types);
+       make_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
+       make_reply_lookup_names(&r_l, &ref, rids, mapped_count, 0x0);
 
-       r_l.status = 0x0;
+       r_l.num_entries  = num_entries;
+       r_l.undoc_buffer = 1;
+       r_l.num_entries2 = num_entries;
 
        /* store the response in the SMB stream */
        lsa_io_r_lookup_names("", &r_l, rdata, 0);
@@ -476,36 +533,16 @@ api_lsa_lookup_names
 static void api_lsa_lookup_names( uint16 vuid, prs_struct *data,
                                   prs_struct *rdata )
 {
-       int i;
        LSA_Q_LOOKUP_NAMES q_l;
-       DOM_SID dom_sids [MAX_LOOKUP_SIDS];
-       uint8   dom_types[MAX_LOOKUP_SIDS];
-
        ZERO_STRUCT(q_l);
-       ZERO_ARRAY(dom_sids);   
 
        /* grab the info class and policy handle */
        lsa_io_q_lookup_names("", &q_l, data, 0);
 
        SMB_ASSERT_ARRAY(q_l.uni_name, q_l.num_entries);
 
-       /* convert received RIDs to strings, so we can do them. */
-       for (i = 0; i < q_l.num_entries; i++)
-       {
-               fstring name;
-               fstrcpy(name, unistr2_to_str(&q_l.uni_name[i]));
-
-               if (!lookup_name(name, &dom_sids[i], &dom_types[i]))
-               {
-                       dom_types[i] = SID_NAME_UNKNOWN;
-               }
-       }
-
        /* construct reply.  return status is always 0x0 */
-       lsa_reply_lookup_names(rdata,
-                              q_l.num_entries,
-                             dom_sids, /* text-converted SIDs */
-                             dom_types); /* SID_NAME_USE types */
+       lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
 }
 
 /***************************************************************************
index 02bfa2e178eace194f435883248717a21e283c30..82dea29d9a15bd32898974ca7aa6a1979458c197 100644 (file)
@@ -150,11 +150,7 @@ static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
 static void api_samr_close_hnd( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_CLOSE_HND q_u;
-
-       /* grab the samr unknown 1 */
        samr_io_q_close_hnd("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_close_hnd(&q_u, rdata);
 }
 
@@ -209,11 +205,7 @@ static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
 static void api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_OPEN_DOMAIN q_u;
-
-       /* grab the samr open */
        samr_io_q_open_domain("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_open_domain(&q_u, rdata);
 }
 
@@ -236,7 +228,7 @@ static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
        /* find the user's rid */
        if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
        {
-               status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
        }
 
        make_samr_r_unknown_2c(&r_u, status);
@@ -256,11 +248,7 @@ static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
 static void api_samr_unknown_2c( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_UNKNOWN_2C q_u;
-
-       /* grab the samr open */
        samr_io_q_unknown_2c("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_unknown_2c(&q_u, rdata);
 }
 
@@ -287,7 +275,7 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
        /* find the user's rid */
        if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
        {
-               status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
        }
 
        if (status == 0x0)
@@ -329,11 +317,7 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
 static void api_samr_unknown_3( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_UNKNOWN_3 q_u;
-
-       /* grab the samr open */
        samr_io_q_unknown_3("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_unknown_3(&q_u, rdata);
 }
 
@@ -380,17 +364,261 @@ static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
 static void api_samr_enum_dom_users( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_ENUM_DOM_USERS q_e;
-
-       /* grab the samr open */
        samr_io_q_enum_dom_users("", &q_e, data, 0);
-
-       /* construct reply. */
        samr_reply_enum_dom_users(&q_e, rdata);
 }
 
 
 /*******************************************************************
- samr_reply_enum_dom_groups
+ samr_reply_add_groupmem
+ ********************************************************************/
+static void samr_reply_add_groupmem(SAMR_Q_ADD_GROUPMEM *q_u,
+                               prs_struct *rdata)
+{
+       SAMR_R_ADD_GROUPMEM r_e;
+       DOM_SID group_sid;
+       uint32 group_rid;
+       fstring group_sid_str;
+
+       r_e.status = 0x0;
+
+       /* find the policy handle.  open a policy on it. */
+       if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &group_sid))
+       {
+               r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+       }
+       else
+       {
+               sid_to_string(group_sid_str, &group_sid);
+               sid_split_rid(&group_sid, &group_rid);
+       }
+
+       if (r_e.status == 0x0)
+       {
+               DEBUG(10,("sid is %s\n", group_sid_str));
+
+               if (sid_equal(&group_sid, &global_sam_sid))
+               {
+                       DEBUG(10,("lookup on Domain SID\n"));
+
+                       become_root(True);
+                       r_e.status = add_group_member(group_rid, q_u->rid) ? 0x0 : 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+                       unbecome_root(True);
+               }
+               else
+               {
+                       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
+               }
+       }
+
+       /* store the response in the SMB stream */
+       samr_io_r_add_groupmem("", &r_e, rdata, 0);
+
+       DEBUG(5,("samr_add_groupmem: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_samr_add_groupmem
+ ********************************************************************/
+static void api_samr_add_groupmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+       SAMR_Q_ADD_GROUPMEM q_e;
+       samr_io_q_add_groupmem("", &q_e, data, 0);
+       samr_reply_add_groupmem(&q_e, rdata);
+}
+
+/*******************************************************************
+ samr_reply_del_groupmem
+ ********************************************************************/
+static void samr_reply_del_groupmem(SAMR_Q_DEL_GROUPMEM *q_u,
+                               prs_struct *rdata)
+{
+       SAMR_R_DEL_GROUPMEM r_e;
+       DOM_SID group_sid;
+       uint32 group_rid;
+       fstring group_sid_str;
+
+       r_e.status = 0x0;
+
+       /* find the policy handle.  open a policy on it. */
+       if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &group_sid))
+       {
+               r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+       }
+       else
+       {
+               sid_to_string(group_sid_str, &group_sid);
+               sid_split_rid(&group_sid, &group_rid);
+       }
+
+       if (r_e.status == 0x0)
+       {
+               DEBUG(10,("sid is %s\n", group_sid_str));
+
+               if (sid_equal(&group_sid, &global_sam_sid))
+               {
+                       DEBUG(10,("lookup on Domain SID\n"));
+
+                       become_root(True);
+                       r_e.status = del_group_member(group_rid, q_u->rid) ? 0x0 : 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+                       unbecome_root(True);
+               }
+               else
+               {
+                       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
+               }
+       }
+
+       /* store the response in the SMB stream */
+       samr_io_r_del_groupmem("", &r_e, rdata, 0);
+
+       DEBUG(5,("samr_del_groupmem: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_samr_del_groupmem
+ ********************************************************************/
+static void api_samr_del_groupmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+       SAMR_Q_DEL_GROUPMEM q_e;
+       samr_io_q_del_groupmem("", &q_e, data, 0);
+       samr_reply_del_groupmem(&q_e, rdata);
+}
+
+/*******************************************************************
+ samr_reply_add_aliasmem
+ ********************************************************************/
+static void samr_reply_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u,
+                               prs_struct *rdata)
+{
+       SAMR_R_ADD_ALIASMEM r_e;
+       DOM_SID alias_sid;
+       uint32 alias_rid;
+       fstring alias_sid_str;
+
+       r_e.status = 0x0;
+
+       /* find the policy handle.  open a policy on it. */
+       if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->alias_pol, &alias_sid))
+       {
+               r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+       }
+       else
+       {
+               sid_to_string(alias_sid_str, &alias_sid);
+               sid_split_rid(&alias_sid, &alias_rid);
+       }
+
+       if (r_e.status == 0x0)
+       {
+               DEBUG(10,("sid is %s\n", alias_sid_str));
+
+               if (sid_equal(&alias_sid, &global_sam_sid))
+               {
+                       DEBUG(10,("add member on Domain SID\n"));
+
+                       become_root(True);
+                       r_e.status = add_alias_member(alias_rid, &q_u->sid) ? 0x0 : 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+                       unbecome_root(True);
+               }
+               else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+               {
+                       DEBUG(10,("add member on BUILTIN SID\n"));
+
+                       become_root(True);
+                       r_e.status = add_builtin_member(alias_rid, &q_u->sid) ? 0x0 : 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+                       unbecome_root(True);
+               }
+               else
+               {
+                       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
+               }
+       }
+
+       /* store the response in the SMB stream */
+       samr_io_r_add_aliasmem("", &r_e, rdata, 0);
+
+       DEBUG(5,("samr_add_aliasmem: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_samr_add_aliasmem
+ ********************************************************************/
+static void api_samr_add_aliasmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+       SAMR_Q_ADD_ALIASMEM q_e;
+       samr_io_q_add_aliasmem("", &q_e, data, 0);
+       samr_reply_add_aliasmem(&q_e, rdata);
+}
+
+/*******************************************************************
+ samr_reply_del_aliasmem
+ ********************************************************************/
+static void samr_reply_del_aliasmem(SAMR_Q_DEL_ALIASMEM *q_u,
+                               prs_struct *rdata)
+{
+       SAMR_R_DEL_ALIASMEM r_e;
+       DOM_SID alias_sid;
+       uint32 alias_rid;
+       fstring alias_sid_str;
+
+       r_e.status = 0x0;
+
+       /* find the policy handle.  open a policy on it. */
+       if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->alias_pol, &alias_sid))
+       {
+               r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+       }
+       else
+       {
+               sid_to_string(alias_sid_str, &alias_sid);
+               sid_split_rid(&alias_sid, &alias_rid);
+       }
+
+       if (r_e.status == 0x0)
+       {
+               DEBUG(10,("sid is %s\n", alias_sid_str));
+
+               if (sid_equal(&alias_sid, &global_sam_sid))
+               {
+                       DEBUG(10,("del member on Domain SID\n"));
+
+                       become_root(True);
+                       r_e.status = del_alias_member(alias_rid, &q_u->sid.sid) ? 0x0 : 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+                       unbecome_root(True);
+               }
+               else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+               {
+                       DEBUG(10,("del member on BUILTIN SID\n"));
+
+                       become_root(True);
+                       r_e.status = del_builtin_member(alias_rid, &q_u->sid.sid) ? 0x0 : 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+                       unbecome_root(True);
+               }
+               else
+               {
+                       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
+               }
+       }
+
+       /* store the response in the SMB stream */
+       samr_io_r_del_aliasmem("", &r_e, rdata, 0);
+
+       DEBUG(5,("samr_del_aliasmem: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_samr_del_aliasmem
+ ********************************************************************/
+static void api_samr_del_aliasmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+       SAMR_Q_DEL_ALIASMEM q_e;
+       samr_io_q_del_aliasmem("", &q_e, data, 0);
+       samr_reply_del_aliasmem(&q_e, rdata);
+}
+
+/*******************************************************************
+ samr_reply_add_groupmem
  ********************************************************************/
 static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
                                prs_struct *rdata)
@@ -479,11 +707,7 @@ static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
 static void api_samr_enum_dom_groups( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_ENUM_DOM_GROUPS q_e;
-
-       /* grab the samr open */
        samr_io_q_enum_dom_groups("", &q_e, data, 0);
-
-       /* construct reply. */
        samr_reply_enum_dom_groups(&q_e, rdata);
 }
 
@@ -669,6 +893,68 @@ static void api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct *
        samr_reply_query_dispinfo(&q_e, rdata);
 }
 
+/*******************************************************************
+ samr_reply_delete_dom_group
+ ********************************************************************/
+static void samr_reply_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP *q_u,
+                               prs_struct *rdata)
+{
+       uint32 status = 0;
+
+       DOM_SID group_sid;
+       uint32 group_rid;
+       fstring group_sid_str;
+
+       SAMR_R_DELETE_DOM_GROUP r_u;
+
+       DEBUG(5,("samr_delete_dom_group: %d\n", __LINE__));
+
+       /* find the policy handle.  open a policy on it. */
+       if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->group_pol, &group_sid))
+       {
+               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+       }
+       else
+       {
+               sid_to_string(group_sid_str, &group_sid     );
+               sid_split_rid(&group_sid, &group_rid);
+       }
+
+       if (status == 0x0)
+       {
+               DEBUG(10,("sid is %s\n", group_sid_str));
+
+               if (sid_equal(&group_sid, &global_sam_sid))
+               {
+                       DEBUG(10,("lookup on Domain SID\n"));
+
+                       become_root(True);
+                       status = del_group_entry(group_rid) ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
+                       unbecome_root(True);
+               }
+               else
+               {
+                       status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+               }
+       }
+
+       make_samr_r_delete_dom_group(&r_u, status);
+
+       /* store the response in the SMB stream */
+       samr_io_r_delete_dom_group("", &r_u, rdata, 0);
+}
+
+/*******************************************************************
+ api_samr_delete_dom_group
+ ********************************************************************/
+static void api_samr_delete_dom_group( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+       SAMR_Q_DELETE_DOM_GROUP q_u;
+       samr_io_q_delete_dom_group("", &q_u, data, 0);
+       samr_reply_delete_dom_group(&q_u, rdata);
+}
+
+
 /*******************************************************************
  samr_reply_query_groupmem
  ********************************************************************/
@@ -759,11 +1045,7 @@ static void samr_reply_query_groupmem(SAMR_Q_QUERY_GROUPMEM *q_u,
 static void api_samr_query_groupmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_QUERY_GROUPMEM q_u;
-
-       /* grab the samr 0x19 */
        samr_io_q_query_groupmem("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_query_groupmem(&q_u, rdata);
 }
 
@@ -804,7 +1086,7 @@ static void samr_reply_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_u,
                }
                else
                {
-                       status = NT_STATUS_INVALID_INFO_CLASS;
+                       status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
                }
        }
 
@@ -823,11 +1105,7 @@ static void samr_reply_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_u,
 static void api_samr_query_groupinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_QUERY_GROUPINFO q_e;
-
-       /* grab the samr open */
        samr_io_q_query_groupinfo("", &q_e, data, 0);
-
-       /* construct reply. */
        samr_reply_query_groupinfo(&q_e, rdata);
 }
 
@@ -862,7 +1140,7 @@ static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
                }
                else
                {
-                       status = NT_STATUS_INVALID_INFO_CLASS;
+                       status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
                }
        }
 
@@ -881,11 +1159,7 @@ static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
 static void api_samr_query_aliasinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_QUERY_ALIASINFO q_e;
-
-       /* grab the samr open */
        samr_io_q_query_aliasinfo("", &q_e, data, 0);
-
-       /* construct reply. */
        samr_reply_query_aliasinfo(&q_e, rdata);
 }
 
@@ -948,22 +1222,105 @@ static void samr_reply_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
 
        if (status == 0x0)
        {
-               DEBUG(10,("sid is %s\n", dom_sid_str));
-
-               if (sid_equal(&dom_sid, &global_sid_S_1_5_20))
-               {
-                       DEBUG(10,("lookup on S-1-5-20\n"));
+               DEBUG(10,("sid is %s\n", dom_sid_str));
+
+               if (sid_equal(&dom_sid, &global_sid_S_1_5_20))
+               {
+                       DEBUG(10,("lookup on S-1-5-20\n"));
+
+                       become_root(True);
+                       getuserbuiltinntnam(sam_pass->nt_name, &mem_grp, &num_rids);
+                       unbecome_root(True);
+               }
+               else if (sid_equal(&dom_sid, &usr_sid))
+               {
+                       DEBUG(10,("lookup on Domain SID\n"));
+
+                       become_root(True);
+                       getuseraliasntnam(sam_pass->nt_name, &mem_grp, &num_rids);
+                       unbecome_root(True);
+               }
+               else
+               {
+                       status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+               }
+       }
+
+       if (status == 0x0 && num_rids > 0)
+       {
+                       rid = malloc(num_rids * sizeof(uint32));
+                       if (mem_grp != NULL && rid != NULL)
+                       {
+                               int i;
+                               for (i = 0; i < num_rids; i++)
+                               {
+                                       rid[i] = mem_grp[i].rid;
+                               }
+                               free(mem_grp);
+               }
+       }
+
+       make_samr_r_query_useraliases(&r_u, num_rids, rid, status);
+
+       /* store the response in the SMB stream */
+       samr_io_r_query_useraliases("", &r_u, rdata, 0);
+
+       if (rid != NULL)
+       {
+               free(rid);
+       }
+
+       DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_query_useraliases
+ ********************************************************************/
+static void api_samr_query_useraliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+       SAMR_Q_QUERY_USERALIASES q_u;
+       samr_io_q_query_useraliases("", &q_u, data, 0);
+       samr_reply_query_useraliases(&q_u, rdata);
+}
+
+/*******************************************************************
+ samr_reply_delete_dom_alias
+ ********************************************************************/
+static void samr_reply_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS *q_u,
+                               prs_struct *rdata)
+{
+       uint32 status = 0;
+
+       DOM_SID alias_sid;
+       uint32 alias_rid;
+       fstring alias_sid_str;
+
+       SAMR_R_DELETE_DOM_ALIAS r_u;
+
+       DEBUG(5,("samr_delete_dom_alias: %d\n", __LINE__));
+
+       /* find the policy handle.  open a policy on it. */
+       if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->alias_pol, &alias_sid))
+       {
+               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+       }
+       else
+       {
+               sid_to_string(alias_sid_str, &alias_sid     );
+               sid_split_rid(&alias_sid, &alias_rid);
+       }
+
+       if (status == 0x0)
+       {
+               DEBUG(10,("sid is %s\n", alias_sid_str));
 
-                       become_root(True);
-                       getuserbuiltinntnam(sam_pass->nt_name, &mem_grp, &num_rids);
-                       unbecome_root(True);
-               }
-               else if (sid_equal(&dom_sid, &usr_sid))
+               if (sid_equal(&alias_sid, &global_sam_sid))
                {
                        DEBUG(10,("lookup on Domain SID\n"));
 
                        become_root(True);
-                       getuseraliasntnam(sam_pass->nt_name, &mem_grp, &num_rids);
+                       status = del_alias_entry(alias_rid) ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
                        unbecome_root(True);
                }
                else
@@ -972,48 +1329,23 @@ static void samr_reply_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
                }
        }
 
-       if (status == 0x0 && num_rids > 0)
-       {
-                       rid = malloc(num_rids * sizeof(uint32));
-                       if (mem_grp != NULL && rid != NULL)
-                       {
-                               int i;
-                               for (i = 0; i < num_rids; i++)
-                               {
-                                       rid[i] = mem_grp[i].rid;
-                               }
-                               free(mem_grp);
-               }
-       }
-
-       make_samr_r_query_useraliases(&r_u, num_rids, rid, status);
+       make_samr_r_delete_dom_alias(&r_u, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_query_useraliases("", &r_u, rdata, 0);
-
-       if (rid != NULL)
-       {
-               free(rid);
-       }
-
-       DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
-
+       samr_io_r_delete_dom_alias("", &r_u, rdata, 0);
 }
 
 /*******************************************************************
- api_samr_query_useraliases
+ api_samr_delete_dom_alias
  ********************************************************************/
-static void api_samr_query_useraliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static void api_samr_delete_dom_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_QUERY_USERALIASES q_u;
-
-       /* grab the samr 0x10 */
-       samr_io_q_query_useraliases("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
-       samr_reply_query_useraliases(&q_u, rdata);
+       SAMR_Q_DELETE_DOM_ALIAS q_u;
+       samr_io_q_delete_dom_alias("", &q_u, data, 0);
+       samr_reply_delete_dom_alias(&q_u, rdata);
 }
 
+
 /*******************************************************************
  samr_reply_query_aliasmem
  ********************************************************************/
@@ -1104,11 +1436,7 @@ static void samr_reply_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_u,
 static void api_samr_query_aliasmem( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_QUERY_ALIASMEM q_u;
-
-       /* grab the samr 0x21 */
        samr_io_q_query_aliasmem("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_query_aliasmem(&q_u, rdata);
 }
 
@@ -1122,25 +1450,31 @@ static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
        uint8  type[MAX_SAM_ENTRIES];
        uint32 status     = 0;
        int i;
-       int num_rids = q_u->num_rids1;
+       int num_rids = q_u->num_names1;
+       DOM_SID pol_sid;
 
        SAMR_R_LOOKUP_NAMES r_u;
 
        DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
 
+       if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &pol_sid))
+       {
+               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+       }
+
        if (num_rids > MAX_SAM_ENTRIES)
        {
                num_rids = MAX_SAM_ENTRIES;
                DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
        }
 
-       SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
+       SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
 
        for (i = 0; i < num_rids && status == 0; i++)
        {
                DOM_SID sid;
                fstring name;
-               fstrcpy(name, unistrn2(q_u->uni_user_name[i].buffer, q_u->uni_user_name[i].uni_str_len));
+               fstrcpy(name, unistr2_to_str(&q_u->uni_name[i]));
 
                status = lookup_name(name, &sid, &(type[i]));
                if (status == 0x0)
@@ -1150,6 +1484,12 @@ static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
                else
                {
                        type[i] = SID_NAME_UNKNOWN;
+                       rid [i] = 0xffffffff;
+               }
+               if (!sid_equal(&pol_sid, &sid))
+               {
+                       rid [i] = 0xffffffff;
+                       type[i] = SID_NAME_UNKNOWN;
                }
        }
 
@@ -1168,11 +1508,7 @@ static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
 static void api_samr_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_LOOKUP_NAMES q_u;
-
-       /* grab the samr lookup names */
        samr_io_q_lookup_names("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_lookup_names(&q_u, rdata);
 }
 
@@ -1213,11 +1549,7 @@ static void samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
 static void api_samr_chgpasswd_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_CHGPASSWD_USER q_u;
-
-       /* unknown 38 command */
        samr_io_q_chgpasswd_user("", &q_u, data, 0);
-
-       /* construct reply. */
        samr_reply_chgpasswd_user(&q_u, rdata);
 }
 
@@ -1246,11 +1578,7 @@ static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
 static void api_samr_unknown_38( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_UNKNOWN_38 q_u;
-
-       /* unknown 38 command */
        samr_io_q_unknown_38("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_unknown_38(&q_u, rdata);
 }
 
@@ -1279,7 +1607,7 @@ static void samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
 
        if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &pol_sid))
        {
-               status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
        }
 
        if (status == 0x0)
@@ -1315,11 +1643,7 @@ static void samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
 static void api_samr_lookup_rids( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_LOOKUP_RIDS q_u;
-
-       /* grab the samr lookup names */
        samr_io_q_lookup_rids("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_lookup_rids(&q_u, rdata);
 }
 
@@ -1389,11 +1713,7 @@ static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
 static void api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_OPEN_USER q_u;
-
-       /* grab the samr unknown 22 */
        samr_io_q_open_user("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_open_user(&q_u, rdata, 0x0);
 }
 
@@ -1506,13 +1826,13 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
        /* search for the handle */
        if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
        {
-               status = NT_STATUS_INVALID_HANDLE;
+               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
 
        /* find the user's rid */
        if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
        {
-               status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
        }
 
        DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
@@ -1552,7 +1872,7 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
 
                        default:
                        {
-                               status = NT_STATUS_INVALID_INFO_CLASS;
+                               status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
 
                                break;
                        }
@@ -1574,11 +1894,7 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
 static void api_samr_query_userinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_QUERY_USERINFO q_u;
-
-       /* grab the samr unknown 24 */
        samr_io_q_query_userinfo("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_query_userinfo(&q_u, rdata);
 }
 
@@ -1608,7 +1924,7 @@ static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
        /* find the user's rid */
        if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
        {
-               status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
        }
 
        if (status == 0x0)
@@ -1661,14 +1977,234 @@ static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
 static void api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_QUERY_USERGROUPS q_u;
-       /* grab the samr unknown 32 */
        samr_io_q_query_usergroups("", &q_u, data, 0);
-
-       /* construct reply. */
        samr_reply_query_usergroups(&q_u, rdata);
 }
 
 
+/*******************************************************************
+ opens a samr alias by rid, returns a policy handle.
+ ********************************************************************/
+static uint32 open_samr_alias(DOM_SID *sid, POLICY_HND *alias_pol,
+                               uint32 alias_rid)
+{
+       BOOL pol_open = False;
+       uint32 status = 0x0;
+
+       /* get a (unique) handle.  open a policy on it. */
+       if (status == 0x0 && !(pol_open = open_lsa_policy_hnd(alias_pol)))
+       {
+               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       DEBUG(0,("TODO: verify that the alias rid exists\n"));
+
+       /* associate a RID with the (unique) handle. */
+       if (status == 0x0 && !set_lsa_policy_samr_rid(alias_pol, alias_rid))
+       {
+               /* oh, whoops.  don't know what error message to return, here */
+               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       sid_append_rid(sid, alias_rid);
+
+       /* associate an alias SID with the (unique) handle. */
+       if (status == 0x0 && !set_lsa_policy_samr_sid(alias_pol, sid))
+       {
+               /* oh, whoops.  don't know what error message to return, here */
+               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       if (status != 0 && pol_open)
+       {
+               close_lsa_policy_hnd(alias_pol);
+       }
+
+       return status;
+}
+
+/*******************************************************************
+ samr_reply_create_dom_alias
+ ********************************************************************/
+static void samr_reply_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u,
+                               prs_struct *rdata)
+{
+       SAMR_R_CREATE_DOM_ALIAS r_u;
+       DOM_SID dom_sid;
+       LOCAL_GRP grp;
+       POLICY_HND alias_pol;
+       uint32 status = 0x0;
+
+       bzero(&alias_pol, sizeof(alias_pol));
+
+       DEBUG(5,("samr_create_dom_alias: %d\n", __LINE__));
+
+       /* find the policy handle.  open a policy on it. */
+       if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->dom_pol)) == -1))
+       {
+               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+       }
+
+       /* find the domain sid */
+       if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->dom_pol, &dom_sid))
+       {
+               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+       }
+
+       if (!sid_equal(&dom_sid, &global_sam_sid))
+       {
+               status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+       }
+
+       if (status == 0x0)
+       {
+               fstrcpy(grp.name, unistr2_to_str(&q_u->uni_acct_desc));
+               fstrcpy(grp.comment, "");
+               grp.rid = 0xffffffff;
+
+               become_root(True);
+               status = add_alias_entry(&grp) ? 0 : 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+               unbecome_root(True);
+       }
+
+       if (status == 0x0)
+       {
+               status = open_samr_alias(&dom_sid, &alias_pol, grp.rid);
+       }
+
+       /* construct the response. */
+       make_samr_r_create_dom_alias(&r_u, &alias_pol, grp.rid, status);
+
+       /* store the response in the SMB stream */
+       samr_io_r_create_dom_alias("", &r_u, rdata, 0);
+
+       DEBUG(5,("samr_create_dom_alias: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_create_dom_alias
+ ********************************************************************/
+static void api_samr_create_dom_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+       SAMR_Q_CREATE_DOM_ALIAS q_u;
+       samr_io_q_create_dom_alias("", &q_u, data, 0);
+       samr_reply_create_dom_alias(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ opens a samr group by rid, returns a policy handle.
+ ********************************************************************/
+static uint32 open_samr_group(DOM_SID *sid, POLICY_HND *group_pol,
+                               uint32 group_rid)
+{
+       BOOL pol_open = False;
+       uint32 status = 0x0;
+
+       /* get a (unique) handle.  open a policy on it. */
+       if (status == 0x0 && !(pol_open = open_lsa_policy_hnd(group_pol)))
+       {
+               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       DEBUG(0,("TODO: verify that the group rid exists\n"));
+
+       /* associate a RID with the (unique) handle. */
+       if (status == 0x0 && !set_lsa_policy_samr_rid(group_pol, group_rid))
+       {
+               /* oh, whoops.  don't know what error message to return, here */
+               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       sid_append_rid(sid, group_rid);
+
+       /* associate an group SID with the (unique) handle. */
+       if (status == 0x0 && !set_lsa_policy_samr_sid(group_pol, sid))
+       {
+               /* oh, whoops.  don't know what error message to return, here */
+               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       if (status != 0 && pol_open)
+       {
+               close_lsa_policy_hnd(group_pol);
+       }
+
+       return status;
+}
+
+/*******************************************************************
+ samr_reply_create_dom_group
+ ********************************************************************/
+static void samr_reply_create_dom_group(SAMR_Q_CREATE_DOM_GROUP *q_u,
+                               prs_struct *rdata)
+{
+       SAMR_R_CREATE_DOM_GROUP r_u;
+       DOM_SID dom_sid;
+       DOMAIN_GRP grp;
+       POLICY_HND group_pol;
+       uint32 status = 0x0;
+
+       bzero(&group_pol, sizeof(group_pol));
+
+       DEBUG(5,("samr_create_dom_group: %d\n", __LINE__));
+
+       /* find the policy handle.  open a policy on it. */
+       if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+       {
+               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+       }
+
+       /* find the domain sid */
+       if (status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &dom_sid))
+       {
+               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+       }
+
+       if (!sid_equal(&dom_sid, &global_sam_sid))
+       {
+               status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+       }
+
+       if (status == 0x0)
+       {
+               fstrcpy(grp.name, unistr2_to_str(&q_u->uni_acct_desc));
+               fstrcpy(grp.comment, "");
+               grp.rid = 0xffffffff;
+               grp.attr = 0x07;
+
+               become_root(True);
+               status = add_group_entry(&grp) ? 0x0 : 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+               unbecome_root(True);
+       }
+
+       if (status == 0x0)
+       {
+               status = open_samr_group(&dom_sid, &group_pol, grp.rid);
+       }
+
+       /* construct the response. */
+       make_samr_r_create_dom_group(&r_u, &group_pol, grp.rid, status);
+
+       /* store the response in the SMB stream */
+       samr_io_r_create_dom_group("", &r_u, rdata, 0);
+
+       DEBUG(5,("samr_create_dom_group: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_create_dom_group
+ ********************************************************************/
+static void api_samr_create_dom_group( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+       SAMR_Q_CREATE_DOM_GROUP q_u;
+       samr_io_q_create_dom_group("", &q_u, data, 0);
+       samr_reply_create_dom_group(&q_u, rdata);
+}
+
+
 /*******************************************************************
  samr_reply_query_dom_info
  ********************************************************************/
@@ -1728,11 +2264,7 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
 static void api_samr_query_dom_info( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_QUERY_DOMAIN_INFO q_e;
-
-       /* grab the samr unknown 8 command */
        samr_io_q_query_dom_info("", &q_e, data, 0);
-
-       /* construct reply. */
        samr_reply_query_dom_info(&q_e, rdata);
 }
 
@@ -1859,11 +2391,7 @@ static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
 static void api_samr_connect_anon( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_CONNECT_ANON q_u;
-
-       /* grab the samr open policy */
        samr_io_q_connect_anon("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_connect_anon(&q_u, rdata);
 }
 
@@ -1912,11 +2440,7 @@ static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
 static void api_samr_connect( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_CONNECT q_u;
-
-       /* grab the samr open policy */
        samr_io_q_connect("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_connect(&q_u, rdata);
 }
 
@@ -1983,11 +2507,7 @@ static void api_samr_open_alias( uint16 vuid, prs_struct *data, prs_struct *rdat
                                 
 {
        SAMR_Q_OPEN_ALIAS q_u;
-
-       /* grab the samr open policy */
        samr_io_q_open_alias("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_open_alias(&q_u, rdata);
 }
 
@@ -1999,47 +2519,27 @@ static void samr_reply_open_group(SAMR_Q_OPEN_GROUP *q_u,
 {
        SAMR_R_OPEN_GROUP r_u;
        DOM_SID sid;
-       BOOL pol_open = False;
 
-       /* set up the SAMR open_group response */
+       DEBUG(5,("samr_open_group: %d\n", __LINE__));
 
        r_u.status = 0x0;
+
+       /* find the domain sid associated with the policy handle */
        if (r_u.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->domain_pol, &sid))
        {
                r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
 
-       /* get a (unique) handle.  open a policy on it. */
-       if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
-       {
-               r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-
-       DEBUG(0,("TODO: verify that the group rid exists\n"));
-
-       /* associate a RID with the (unique) handle. */
-       if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_group))
-       {
-               /* oh, whoops.  don't know what error message to return, here */
-               r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-
-       sid_append_rid(&sid, q_u->rid_group);
-
-       /* associate an group SID with the (unique) handle. */
-       if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.pol), &sid))
+       if (r_u.status == 0x0 && !sid_equal(&sid, &global_sam_sid))
        {
-               /* oh, whoops.  don't know what error message to return, here */
-               r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               r_u.status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
        }
 
-       if (r_u.status != 0 && pol_open)
+       if (r_u.status == 0x0)
        {
-               close_lsa_policy_hnd(&(r_u.pol));
+               r_u.status = open_samr_group(&sid, &r_u.pol, q_u->rid_group);
        }
 
-       DEBUG(5,("samr_open_group: %d\n", __LINE__));
-
        /* store the response in the SMB stream */
        samr_io_r_open_group("", &r_u, rdata, 0);
 
@@ -2054,11 +2554,7 @@ static void api_samr_open_group( uint16 vuid, prs_struct *data, prs_struct *rdat
                                 
 {
        SAMR_Q_OPEN_GROUP q_u;
-
-       /* grab the samr open policy */
        samr_io_q_open_group("", &q_u, data, 0);
-
-       /* construct reply.  always indicate success */
        samr_reply_open_group(&q_u, rdata);
 }
 
@@ -2076,6 +2572,14 @@ static struct api_struct api_samr_cmds [] =
        { "SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES, api_samr_query_useraliases},
        { "SAMR_QUERY_ALIASMEM"   , SAMR_QUERY_ALIASMEM   , api_samr_query_aliasmem   },
        { "SAMR_QUERY_GROUPMEM"   , SAMR_QUERY_GROUPMEM   , api_samr_query_groupmem   },
+       { "SAMR_ADD_ALIASMEM"     , SAMR_ADD_ALIASMEM     , api_samr_del_aliasmem     },
+       { "SAMR_DEL_ALIASMEM"     , SAMR_DEL_ALIASMEM     , api_samr_add_aliasmem     },
+       { "SAMR_ADD_GROUPMEM"     , SAMR_ADD_GROUPMEM     , api_samr_del_groupmem     },
+       { "SAMR_DEL_GROUPMEM"     , SAMR_DEL_GROUPMEM     , api_samr_add_groupmem     },
+       { "SAMR_DELETE_DOM_GROUP" , SAMR_DELETE_DOM_GROUP , api_samr_delete_dom_group },
+       { "SAMR_DELETE_DOM_ALIAS" , SAMR_DELETE_DOM_ALIAS , api_samr_delete_dom_alias },
+       { "SAMR_CREATE_DOM_GROUP" , SAMR_CREATE_DOM_GROUP , api_samr_create_dom_group },
+       { "SAMR_CREATE_DOM_ALIAS" , SAMR_CREATE_DOM_ALIAS , api_samr_create_dom_alias },
        { "SAMR_LOOKUP_NAMES"     , SAMR_LOOKUP_NAMES     , api_samr_lookup_names     },
        { "SAMR_OPEN_USER"        , SAMR_OPEN_USER        , api_samr_open_user        },
        { "SAMR_QUERY_USERINFO"   , SAMR_QUERY_USERINFO   , api_samr_query_userinfo   },
index ac9da8b2ea25d20d9929c2943b3ad7c31cd2ecbd..fb2accfc4d23eef57f21d14f0477c544846104b8 100644 (file)
@@ -172,9 +172,9 @@ void cmd_sam_test(struct client_info *info)
 }
 
 /****************************************************************************
-SAM add alias member.
+SAM delete alias member.
 ****************************************************************************/
-void cmd_sam_add_aliasmem(struct client_info *info)
+void cmd_sam_del_aliasmem(struct client_info *info)
 {
        fstring srv_name;
        fstring domain;
@@ -205,7 +205,7 @@ void cmd_sam_add_aliasmem(struct client_info *info)
 
        if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
-               fprintf(out_hnd, "addaliasmem: <alias rid> [member sid1] [member sid2] ...\n");
+               fprintf(out_hnd, "delaliasmem: <alias rid> [member sid1] [member sid2] ...\n");
                return;
        }
        alias_rid = get_number(tmp);
@@ -228,16 +228,258 @@ void cmd_sam_add_aliasmem(struct client_info *info)
        /* connect to the domain */
        res1 = res ? samr_open_alias(smb_cli,
                    &info->dom.samr_pol_open_domain,
-                   alias_rid, &alias_pol) : False;
+                   0x000f001f, alias_rid, &alias_pol) : False;
 
        while (next_token(NULL, tmp, NULL, sizeof(tmp)) && res2 && res1)
        {
-               /* get a sid, add a member to the alias */
+               /* get a sid, delete a member from the alias */
                res2 = res2 ? string_to_sid(&member_sid, tmp) : False;
-               res2 = res2 ? samr_add_aliasmem(smb_cli, &alias_pol, &member_sid) : False;
+               res2 = res2 ? samr_del_aliasmem(smb_cli, &alias_pol, &member_sid) : False;
 
                if (res2)
                {
+                       fprintf(out_hnd, "SID deleted from Alias 0x%x: %s\n", alias_rid, tmp);
+               }
+       }
+
+       res1 = res1 ? samr_close(smb_cli, &alias_pol) : False;
+       res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
+       res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
+
+       if (res && res1 && res2)
+       {
+               DEBUG(5,("cmd_sam_del_aliasmem: succeeded\n"));
+               fprintf(out_hnd, "Delete Domain Alias Member: OK\n");
+       }
+       else
+       {
+               DEBUG(5,("cmd_sam_del_aliasmem: failed\n"));
+               fprintf(out_hnd, "Delete Domain Alias Member: FAILED\n");
+       }
+}
+
+/****************************************************************************
+SAM delete alias.
+****************************************************************************/
+void cmd_sam_delete_dom_alias(struct client_info *info)
+{
+       fstring srv_name;
+       fstring domain;
+       fstring name;
+       fstring sid;
+       DOM_SID sid1;
+       POLICY_HND alias_pol;
+       BOOL res = True;
+       BOOL res1 = True;
+       BOOL res2 = True;
+       uint32 flags = 0x200003f3; /* absolutely no idea. */
+       uint32 alias_rid = 0;
+       const char *names[1];
+       uint32 rid [MAX_LOOKUP_SIDS];
+       uint32 type[MAX_LOOKUP_SIDS];
+       uint32 num_rids;
+
+       sid_copy(&sid1, &info->dom.level5_sid);
+       sid_to_string(sid, &sid1);
+       fstrcpy(domain, info->dom.level5_dom);
+
+       if (sid1.num_auths == 0)
+       {
+               fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+               return;
+       }
+
+       fstrcpy(srv_name, "\\\\");
+       fstrcat(srv_name, info->dest_host);
+       strupper(srv_name);
+
+       if (!next_token(NULL, name, NULL, sizeof(name)))
+       {
+               fprintf(out_hnd, "delalias <alias name>\n");
+               return;
+       }
+
+       fprintf(out_hnd, "SAM Delete Domain Alias\n");
+
+       /* open SAMR session.  negotiate credentials */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+       /* establish a connection. */
+       res = res ? samr_connect(smb_cli, 
+                               srv_name, 0x00000020,
+                               &info->dom.samr_pol_connect) : False;
+
+       /* connect to the domain */
+       res = res ? samr_open_domain(smb_cli, 
+                   &info->dom.samr_pol_connect, flags, &sid1,
+                   &info->dom.samr_pol_open_domain) : False;
+
+       names[0] = name;
+
+       res1 = res ? samr_query_lookup_names(smb_cli,
+                   &info->dom.samr_pol_open_domain, 0x000003e8,
+                   1, names,
+                   &num_rids, rid, type) : False;
+
+       if (res1 && num_rids == 1)
+       {
+               alias_rid = rid[0];
+       }
+
+       /* connect to the domain */
+       res1 = res1 ? samr_open_alias(smb_cli,
+                   &info->dom.samr_pol_open_domain,
+                   0x000f001f, alias_rid, &alias_pol) : False;
+
+       res2 = res1 ? samr_delete_dom_alias(smb_cli, &alias_pol) : False;
+
+       res1 = res1 ? samr_close(smb_cli, &alias_pol) : False;
+       res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
+       res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
+
+       if (res && res1 && res2)
+       {
+               DEBUG(5,("cmd_sam_delete_dom_alias: succeeded\n"));
+               fprintf(out_hnd, "Delete Domain Alias: OK\n");
+       }
+       else
+       {
+               DEBUG(5,("cmd_sam_delete_dom_alias: failed\n"));
+               fprintf(out_hnd, "Delete Domain Alias: FAILED\n");
+       }
+}
+
+
+/****************************************************************************
+SAM add alias member.
+****************************************************************************/
+void cmd_sam_add_aliasmem(struct client_info *info)
+{
+       fstring srv_name;
+       fstring domain;
+       fstring tmp;
+       fstring sid;
+       DOM_SID sid1;
+       POLICY_HND alias_pol;
+       BOOL res = True;
+       BOOL res1 = True;
+       BOOL res2 = True;
+       BOOL res3 = True;
+       BOOL res4 = True;
+       uint32 flags = 0x200003f3; /* absolutely no idea. */
+       uint32 alias_rid;
+       const char **names = NULL;
+       uint32 num_names = 0;
+       DOM_SID *sids; 
+       uint32 num_sids;
+       int i;
+
+       sid_copy(&sid1, &info->dom.level5_sid);
+       sid_to_string(sid, &sid1);
+       fstrcpy(domain, info->dom.level5_dom);
+
+       if (sid1.num_auths == 0)
+       {
+               fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+               return;
+       }
+
+       fstrcpy(srv_name, "\\\\");
+       fstrcat(srv_name, info->dest_host);
+       strupper(srv_name);
+
+       while (next_token(NULL, tmp, NULL, sizeof(tmp)))
+       {
+               num_names++;
+               names = Realloc(names, num_names * sizeof(char*));
+               if (names == NULL)
+               {
+                       DEBUG(0,("Realloc returned NULL\n"));
+                       return;
+               }
+               names[num_names-1] = strdup(tmp);
+       }
+
+       if (num_names < 2)
+       {
+               fprintf(out_hnd, "addaliasmem <group name> [member name1] [member name2] ...\n");
+               return;
+       }
+       
+       fprintf(out_hnd, "SAM Domain Alias Member\n");
+
+       /* open LSARPC session. */
+       res3 = res3 ? cli_nt_session_open(smb_cli, PIPE_LSARPC) : False;
+
+       /* lookup domain controller; receive a policy handle */
+       res3 = res3 ? lsa_open_policy(smb_cli,
+                               srv_name,
+                               &info->dom.lsa_info_pol, True) : False;
+
+       /* send lsa lookup sids call */
+       res4 = res3 ? lsa_lookup_names(smb_cli, 
+                                      &info->dom.lsa_info_pol,
+                                      num_names, names, 
+                                      &sids, &num_sids) : False;
+
+       res3 = res3 ? lsa_close(smb_cli, &info->dom.lsa_info_pol) : False;
+
+       cli_nt_session_close(smb_cli);
+
+       res4 = num_sids < 2 ? False : res4;
+
+       if (res4)
+       {
+               /*
+                * accept domain sid or builtin sid
+                */
+
+               DOM_SID sid_1_5_20;
+               string_to_sid(&sid_1_5_20, "S-1-5-32");
+               sid_split_rid(&sids[0], &alias_rid);
+
+               if (sid_equal(&sids[0], &sid_1_5_20))
+               {
+                       sid_copy(&sid1, &sid_1_5_20);
+               }
+               else if (!sid_equal(&sids[0], &sid1))
+               {       
+                       res4 = False;
+               }
+       }
+
+       /* open SAMR session.  negotiate credentials */
+       res = res4 ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+       /* establish a connection. */
+       res = res ? samr_connect(smb_cli, 
+                               srv_name, 0x00000020,
+                               &info->dom.samr_pol_connect) : False;
+
+       /* connect to the domain */
+       res = res ? samr_open_domain(smb_cli, 
+                   &info->dom.samr_pol_connect, flags, &sid1,
+                   &info->dom.samr_pol_open_domain) : False;
+
+       /* connect to the domain */
+       res1 = res ? samr_open_alias(smb_cli,
+                   &info->dom.samr_pol_open_domain,
+                   0x000f001f, alias_rid, &alias_pol) : False;
+
+       for (i = 1; i < num_sids && res2 && res1; i++)
+       {
+               /* add a member to the alias */
+               res2 = res2 ? samr_add_aliasmem(smb_cli, &alias_pol, &sids[i]) : False;
+
+               if (res2)
+               {
+                       sid_to_string(tmp, &sids[i]);
                        fprintf(out_hnd, "SID added to Alias 0x%x: %s\n", alias_rid, tmp);
                }
        }
@@ -249,6 +491,23 @@ void cmd_sam_add_aliasmem(struct client_info *info)
        /* close the session */
        cli_nt_session_close(smb_cli);
 
+       if (sids != NULL)
+       {
+               free(sids);
+       }
+       
+       if (names != NULL)
+       {
+               for (i = 0; i < num_names; i++)
+               {
+                       if (names[i] != NULL)
+                       {
+                               free(((char**)(names))[i]);
+                       }
+               }
+               free(names);
+       }
+       
        if (res && res1 && res2)
        {
                DEBUG(5,("cmd_sam_add_aliasmem: succeeded\n"));
@@ -349,9 +608,9 @@ void cmd_sam_create_dom_alias(struct client_info *info)
 
 
 /****************************************************************************
-SAM add group member.
+SAM delete group member.
 ****************************************************************************/
-void cmd_sam_add_groupmem(struct client_info *info)
+void cmd_sam_del_groupmem(struct client_info *info)
 {
        fstring srv_name;
        fstring domain;
@@ -382,7 +641,7 @@ void cmd_sam_add_groupmem(struct client_info *info)
 
        if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
-               fprintf(out_hnd, "addgroupmem: <group rid> [member rid1] [member rid2] ...\n");
+               fprintf(out_hnd, "delgroupmem: <group rid> [member rid1] [member rid2] ...\n");
                return;
        }
        group_rid = get_number(tmp);
@@ -409,13 +668,223 @@ void cmd_sam_add_groupmem(struct client_info *info)
 
        while (next_token(NULL, tmp, NULL, sizeof(tmp)) && res2 && res1)
        {
-               /* get a rid, add a member to the group */
+               /* get a rid, delete a member from the group */
                member_rid = get_number(tmp);
-               res2 = res2 ? samr_add_groupmem(smb_cli, &group_pol, member_rid) : False;
+               res2 = res2 ? samr_del_groupmem(smb_cli, &group_pol, member_rid) : False;
+
+               if (res2)
+               {
+                       fprintf(out_hnd, "RID deleted from Group 0x%x: 0x%x\n", group_rid, member_rid);
+               }
+       }
+
+       res1 = res1 ? samr_close(smb_cli, &group_pol) : False;
+       res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
+       res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
+
+       if (res && res1 && res2)
+       {
+               DEBUG(5,("cmd_sam_del_groupmem: succeeded\n"));
+               fprintf(out_hnd, "Add Domain Group Member: OK\n");
+       }
+       else
+       {
+               DEBUG(5,("cmd_sam_del_groupmem: failed\n"));
+               fprintf(out_hnd, "Add Domain Group Member: FAILED\n");
+       }
+}
+
+
+/****************************************************************************
+SAM delete group.
+****************************************************************************/
+void cmd_sam_delete_dom_group(struct client_info *info)
+{
+       fstring srv_name;
+       fstring domain;
+       fstring name;
+       fstring sid;
+       DOM_SID sid1;
+       POLICY_HND group_pol;
+       BOOL res = True;
+       BOOL res1 = True;
+       BOOL res2 = True;
+       uint32 flags = 0x200003f3; /* absolutely no idea. */
+       uint32 group_rid = 0;
+       const char *names[1];
+       uint32 rid [MAX_LOOKUP_SIDS];
+       uint32 type[MAX_LOOKUP_SIDS];
+       uint32 num_rids;
+
+       sid_copy(&sid1, &info->dom.level5_sid);
+       sid_to_string(sid, &sid1);
+       fstrcpy(domain, info->dom.level5_dom);
+
+       if (sid1.num_auths == 0)
+       {
+               fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+               return;
+       }
+
+       fstrcpy(srv_name, "\\\\");
+       fstrcat(srv_name, info->dest_host);
+       strupper(srv_name);
+
+       if (!next_token(NULL, name, NULL, sizeof(name)))
+       {
+               fprintf(out_hnd, "delgroup <group name>\n");
+               return;
+       }
+
+       fprintf(out_hnd, "SAM Delete Domain Group\n");
+
+       /* open SAMR session.  negotiate credentials */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+       /* establish a connection. */
+       res = res ? samr_connect(smb_cli, 
+                               srv_name, 0x00000020,
+                               &info->dom.samr_pol_connect) : False;
+
+       /* connect to the domain */
+       res = res ? samr_open_domain(smb_cli, 
+                   &info->dom.samr_pol_connect, flags, &sid1,
+                   &info->dom.samr_pol_open_domain) : False;
+
+       names[0] = name;
+
+       res1 = res ? samr_query_lookup_names(smb_cli,
+                   &info->dom.samr_pol_open_domain, 0x000003e8,
+                   1, names,
+                   &num_rids, rid, type) : False;
+
+       if (res1 && num_rids == 1)
+       {
+               group_rid = rid[0];
+       }
+
+       /* connect to the domain */
+       res1 = res1 ? samr_open_group(smb_cli,
+                   &info->dom.samr_pol_open_domain,
+                   0x0000001f, group_rid, &group_pol) : False;
+
+       res2 = res1 ? samr_delete_dom_group(smb_cli, &group_pol) : False;
+
+       res1 = res1 ? samr_close(smb_cli, &group_pol) : False;
+       res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_open_domain) : False;
+       res  = res  ? samr_close(smb_cli, &info->dom.samr_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
+
+       if (res && res1 && res2)
+       {
+               DEBUG(5,("cmd_sam_delete_dom_group: succeeded\n"));
+               fprintf(out_hnd, "Delete Domain Group: OK\n");
+       }
+       else
+       {
+               DEBUG(5,("cmd_sam_delete_dom_group: failed\n"));
+               fprintf(out_hnd, "Delete Domain Group: FAILED\n");
+       }
+}
+
+
+/****************************************************************************
+SAM add group member.
+****************************************************************************/
+void cmd_sam_add_groupmem(struct client_info *info)
+{
+       fstring srv_name;
+       fstring domain;
+       fstring tmp;
+       fstring sid;
+       DOM_SID sid1;
+       POLICY_HND group_pol;
+       BOOL res = True;
+       BOOL res1 = True;
+       BOOL res2 = True;
+       uint32 flags = 0x200003f3; /* absolutely no idea. */
+       uint32 group_rid = 0;
+       const char **names = NULL;
+       uint32 num_names = 0;
+       uint32 rid [MAX_LOOKUP_SIDS];
+       uint32 type[MAX_LOOKUP_SIDS];
+       uint32 num_rids;
+       int i;
+
+       sid_copy(&sid1, &info->dom.level5_sid);
+       sid_to_string(sid, &sid1);
+       fstrcpy(domain, info->dom.level5_dom);
+
+       if (sid1.num_auths == 0)
+       {
+               fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+               return;
+       }
+
+       fstrcpy(srv_name, "\\\\");
+       fstrcat(srv_name, info->dest_host);
+       strupper(srv_name);
+
+       while (next_token(NULL, tmp, NULL, sizeof(tmp)))
+       {
+               num_names++;
+               names = Realloc(names, num_names * sizeof(char*));
+               if (names == NULL)
+               {
+                       DEBUG(0,("Realloc returned NULL\n"));
+                       return;
+               }
+               names[num_names-1] = strdup(tmp);
+       }
+
+       if (num_names < 2)
+       {
+               fprintf(out_hnd, "addgroupmem <group name> [member name1] [member name2] ...\n");
+               return;
+       }
+       
+       fprintf(out_hnd, "SAM Add Domain Group member\n");
+
+       /* open SAMR session.  negotiate credentials */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+       /* establish a connection. */
+       res = res ? samr_connect(smb_cli, 
+                               srv_name, 0x00000020,
+                               &info->dom.samr_pol_connect) : False;
+
+       /* connect to the domain */
+       res = res ? samr_open_domain(smb_cli, 
+                   &info->dom.samr_pol_connect, flags, &sid1,
+                   &info->dom.samr_pol_open_domain) : False;
+
+       res1 = res ? samr_query_lookup_names(smb_cli,
+                   &info->dom.samr_pol_open_domain, 0x000003e8,
+                   num_names, names,
+                   &num_rids, rid, type) : False;
+
+       if (res1 && num_rids != 0)
+       {
+               group_rid = rid[0];
+       }
+
+       /* connect to the domain */
+       res1 = res1 ? samr_open_group(smb_cli,
+                   &info->dom.samr_pol_open_domain,
+                   0x0000001f, group_rid, &group_pol) : False;
+
+       for (i = 1; i < num_rids && res2 && res1; i++)
+       {
+               res2 = res2 ? samr_add_groupmem(smb_cli, &group_pol, rid[i]) : False;
 
                if (res2)
                {
-                       fprintf(out_hnd, "RID added to Group 0x%x: 0x%x\n", group_rid, member_rid);
+                       fprintf(out_hnd, "RID added to Group 0x%x: 0x%x\n", group_rid, rid[i]);
                }
        }
 
@@ -426,6 +895,18 @@ void cmd_sam_add_groupmem(struct client_info *info)
        /* close the session */
        cli_nt_session_close(smb_cli);
 
+       if (names != NULL)
+       {
+               for (i = 0; i < num_names; i++)
+               {
+                       if (names[i] != NULL)
+                       {
+                               free(((char**)(names))[i]);
+                       }
+               }
+               free(names);
+       }
+       
        if (res && res1 && res2)
        {
                DEBUG(5,("cmd_sam_add_groupmem: succeeded\n"));
@@ -1042,10 +1523,6 @@ void cmd_sam_enum_aliases(struct client_info *info)
                                DOM_SID **sids = NULL;
                                int i;
 
-                               /* jeremy, you removed all the independent fnums
-                                * i put into the nt client code.  this is the reason
-                                * why they are all needed.
-                                */
                                uint16 old_fnum = smb_cli->nt_pipe_fnum;
 
                                if (num_aliases != 0)
index 400faffef4a7d2121257804de9de8ff548d59c05..f207bd507c33bf051f26567e997f4f34abcb696f 100644 (file)
@@ -128,6 +128,8 @@ struct
   {"addaliasmem",cmd_sam_add_aliasmem,"<alias rid> [member sid1] [member sid2] ... SAM Add Domain Alias Member"},
   {"creategroup",cmd_sam_create_dom_group,"SAM Create Domain Group"},
   {"createalias",cmd_sam_create_dom_alias,"SAM Create Domain Alias"},
+  {"delgroup",   cmd_sam_delete_dom_group,"SAM Delete Domain Group"},
+  {"delalias",   cmd_sam_delete_dom_alias,"SAM Delete Domain Alias"},
   {"ntpass",     cmd_sam_ntchange_pwd, "NT SAM Password Change"},
   {"samuser",    cmd_sam_query_user,   "<username> SAM User Query (experimental!)"},
   {"samtest",    cmd_sam_test      ,   "SAM User Encrypted RPC test (experimental!)"},