diff options
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/groupdb/aliasdb.c | 43 | ||||
-rw-r--r-- | source3/groupdb/aliasfile.c | 6 | ||||
-rw-r--r-- | source3/groupdb/aliasunix.c | 39 | ||||
-rw-r--r-- | source3/groupdb/builtindb.c | 16 | ||||
-rw-r--r-- | source3/groupdb/builtinunix.c | 27 | ||||
-rw-r--r-- | source3/groupdb/groupdb.c | 43 | ||||
-rw-r--r-- | source3/groupdb/groupfile.c | 6 | ||||
-rw-r--r-- | source3/groupdb/groupunix.c | 40 | ||||
-rw-r--r-- | source3/include/proto.h | 56 | ||||
-rw-r--r-- | source3/include/rpc_samr.h | 38 | ||||
-rw-r--r-- | source3/include/smb.h | 36 | ||||
-rw-r--r-- | source3/lsarpcd/srv_lsa.c | 133 | ||||
-rw-r--r-- | source3/rpc_client/cli_lsarpc.c | 5 | ||||
-rw-r--r-- | source3/rpc_client/cli_samr.c | 374 | ||||
-rw-r--r-- | source3/rpc_parse/parse_lsa.c | 4 | ||||
-rw-r--r-- | source3/rpc_parse/parse_misc.c | 4 | ||||
-rw-r--r-- | source3/rpc_parse/parse_samr.c | 117 | ||||
-rw-r--r-- | source3/rpc_server/srv_lookup.c | 10 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa.c | 133 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr.c | 766 | ||||
-rw-r--r-- | source3/rpcclient/cmd_samr.c | 509 | ||||
-rw-r--r-- | source3/rpcclient/rpcclient.c | 2 |
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!)"}, |