summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/groupdb/aliasdb.c43
-rw-r--r--source3/groupdb/aliasfile.c6
-rw-r--r--source3/groupdb/aliasunix.c39
-rw-r--r--source3/groupdb/builtindb.c16
-rw-r--r--source3/groupdb/builtinunix.c27
-rw-r--r--source3/groupdb/groupdb.c43
-rw-r--r--source3/groupdb/groupfile.c6
-rw-r--r--source3/groupdb/groupunix.c40
-rw-r--r--source3/include/proto.h56
-rw-r--r--source3/include/rpc_samr.h38
-rw-r--r--source3/include/smb.h36
-rw-r--r--source3/lsarpcd/srv_lsa.c133
-rw-r--r--source3/rpc_client/cli_lsarpc.c5
-rw-r--r--source3/rpc_client/cli_samr.c374
-rw-r--r--source3/rpc_parse/parse_lsa.c4
-rw-r--r--source3/rpc_parse/parse_misc.c4
-rw-r--r--source3/rpc_parse/parse_samr.c117
-rw-r--r--source3/rpc_server/srv_lookup.c10
-rw-r--r--source3/rpc_server/srv_lsa.c133
-rw-r--r--source3/rpc_server/srv_samr.c766
-rw-r--r--source3/rpcclient/cmd_samr.c509
-rw-r--r--source3/rpcclient/rpcclient.c2
23 files changed, 2068 insertions, 341 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index a486618770..d288767d0e 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -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 \
diff --git a/source3/groupdb/aliasdb.c b/source3/groupdb/aliasdb.c
index 011eee0f3d..b787012b4d 100644
--- a/source3/groupdb/aliasdb.c
+++ b/source3/groupdb/aliasdb.c
@@ -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;
}
/************************************************************************
@@ -366,6 +380,29 @@ BOOL mod_alias_entry(LOCAL_GRP* 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.
*************************************************************************/
diff --git a/source3/groupdb/aliasfile.c b/source3/groupdb/aliasfile.c
index 4ae2c25b94..00638f9411 100644
--- a/source3/groupdb/aliasfile.c
+++ b/source3/groupdb/aliasfile.c
@@ -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)
diff --git a/source3/groupdb/aliasunix.c b/source3/groupdb/aliasunix.c
index f9b93bbce4..f9537ddeb4 100644
--- a/source3/groupdb/aliasunix.c
+++ b/source3/groupdb/aliasunix.c
@@ -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 */
};
diff --git a/source3/groupdb/builtindb.c b/source3/groupdb/builtindb.c
index a840c396f9..3b09b6225d 100644
--- a/source3/groupdb/builtindb.c
+++ b/source3/groupdb/builtindb.c
@@ -366,6 +366,22 @@ BOOL mod_builtin_entry(LOCAL_GRP* 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.
*************************************************************************/
diff --git a/source3/groupdb/builtinunix.c b/source3/groupdb/builtinunix.c
index 3fa28b63ae..c8ea767a77 100644
--- a/source3/groupdb/builtinunix.c
+++ b/source3/groupdb/builtinunix.c
@@ -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 */
};
diff --git a/source3/groupdb/groupdb.c b/source3/groupdb/groupdb.c
index 6bd6c34442..ed09560b3a 100644
--- a/source3/groupdb/groupdb.c
+++ b/source3/groupdb/groupdb.c
@@ -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.
************************************************************************/
@@ -361,6 +384,22 @@ BOOL mod_group_entry(DOMAIN_GRP* 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.
*************************************************************************/
diff --git a/source3/groupdb/groupfile.c b/source3/groupdb/groupfile.c
index e20ba6434c..0e10b801d8 100644
--- a/source3/groupdb/groupfile.c
+++ b/source3/groupdb/groupfile.c
@@ -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)
diff --git a/source3/groupdb/groupunix.c b/source3/groupdb/groupunix.c
index 154e23338d..35f386cbf8 100644
--- a/source3/groupdb/groupunix.c
+++ b/source3/groupdb/groupunix.c
@@ -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 */
};
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 647e8fdff9..2e0f42e575 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
index c35761ffeb..a3090cefd6 100644
--- a/source3/include/rpc_samr.h
+++ b/source3/include/rpc_samr.h
@@ -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 */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index e4191f706d..1ed4ea7089 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -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
diff --git a/source3/lsarpcd/srv_lsa.c b/source3/lsarpcd/srv_lsa.c
index 62c8f8a0cd..947de768b5 100644
--- a/source3/lsarpcd/srv_lsa.c
+++ b/source3/lsarpcd/srv_lsa.c
@@ -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);
}
/***************************************************************************
diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c
index 0516cee96d..f0c9bdfe16 100644
--- a/source3/rpc_client/cli_lsarpc.c
+++ b/source3/rpc_client/cli_lsarpc.c
@@ -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
{
diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c
index 4fc1c3f5a0..e950269ec3 100644
--- a/source3/rpc_client/cli_samr.c
+++ b/source3/rpc_client/cli_samr.c
@@ -150,6 +150,38 @@ BOOL get_samr_query_usergroups(struct cli_state *cli,
}
/****************************************************************************
+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
****************************************************************************/
BOOL get_samr_query_groupmem(struct cli_state *cli,
@@ -182,6 +214,37 @@ BOOL get_samr_query_groupmem(struct cli_state *cli,
}
/****************************************************************************
+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
****************************************************************************/
BOOL get_samr_query_aliasmem(struct cli_state *cli,
@@ -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);
@@ -896,6 +960,61 @@ BOOL samr_open_alias(struct cli_state *cli,
}
/****************************************************************************
+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
****************************************************************************/
BOOL samr_add_aliasmem(struct cli_state *cli,
@@ -951,6 +1070,61 @@ BOOL samr_add_aliasmem(struct cli_state *cli,
}
/****************************************************************************
+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
****************************************************************************/
BOOL samr_create_dom_alias(struct cli_state *cli,
@@ -1122,6 +1296,61 @@ BOOL samr_open_group(struct cli_state *cli,
}
/****************************************************************************
+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
****************************************************************************/
BOOL samr_add_groupmem(struct cli_state *cli,
@@ -1177,6 +1406,60 @@ BOOL samr_add_groupmem(struct cli_state *cli,
}
/****************************************************************************
+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
****************************************************************************/
BOOL samr_create_dom_group(struct cli_state *cli,
@@ -1349,6 +1632,91 @@ BOOL samr_open_domain(struct cli_state *cli,
}
/****************************************************************************
+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
****************************************************************************/
BOOL samr_query_lookup_rids(struct cli_state *cli,
diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c
index 9781e3cfab..0b294b84f3 100644
--- a/source3/rpc_parse/parse_lsa.c
+++ b/source3/rpc_parse/parse_lsa.c
@@ -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;
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
index 18c5f23ce3..fdc67d0905 100644
--- a/source3/rpc_parse/parse_misc.c
+++ b/source3/rpc_parse/parse_misc.c
@@ -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;
}
/*******************************************************************
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index 5460d4773b..bfcc811aea 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -2913,6 +2913,22 @@ void samr_io_q_create_dom_alias(char *desc, SAMR_Q_CREATE_DOM_ALIAS *q_u, prs_s
}
/*******************************************************************
+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.
********************************************************************/
void samr_io_r_create_dom_alias(char *desc, SAMR_R_CREATE_DOM_ALIAS *r_u, prs_struct *ps, int depth)
@@ -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
diff --git a/source3/rpc_server/srv_lookup.c b/source3/rpc_server/srv_lookup.c
index c97a4cd0b9..70183636d1 100644
--- a/source3/rpc_server/srv_lookup.c
+++ b/source3/rpc_server/srv_lookup.c
@@ -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
diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c
index 62c8f8a0cd..947de768b5 100644
--- a/source3/rpc_server/srv_lsa.c
+++ b/source3/rpc_server/srv_lsa.c
@@ -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);
}
/***************************************************************************
diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
index 02bfa2e178..82dea29d9a 100644
--- a/source3/rpc_server/srv_samr.c
+++ b/source3/rpc_server/srv_samr.c
@@ -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);
}
@@ -670,6 +894,68 @@ static void api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct *
}
/*******************************************************************
+ 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
********************************************************************/
static void samr_reply_query_groupmem(SAMR_Q_QUERY_GROUPMEM *q_u,
@@ -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);
}
@@ -1006,15 +1280,73 @@ static void samr_reply_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
static void api_samr_query_useraliases( 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_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));
+
+ if (sid_equal(&alias_sid, &global_sam_sid))
+ {
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ become_root(True);
+ status = del_alias_entry(alias_rid) ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
+ unbecome_root(True);
+ }
+ else
+ {
+ status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ }
+ }
+
+ make_samr_r_delete_dom_alias(&r_u, status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_delete_dom_alias("", &r_u, rdata, 0);
+}
+
+/*******************************************************************
+ api_samr_delete_dom_alias
+ ********************************************************************/
+static void api_samr_delete_dom_alias( uint16 vuid, prs_struct *data, prs_struct *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
********************************************************************/
static void samr_reply_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_u,
@@ -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,15 +1977,235 @@ 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
********************************************************************/
static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
@@ -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 },
diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c
index ac9da8b2ea..fb2accfc4d 100644
--- a/source3/rpcclient/cmd_samr.c
+++ b/source3/rpcclient/cmd_samr.c
@@ -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)
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 400faffef4..f207bd507c 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -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!)"},