diff options
-rw-r--r-- | source3/include/proto.h | 10 | ||||
-rw-r--r-- | source3/include/rpc_samr.h | 23 | ||||
-rw-r--r-- | source3/lib/sids.c | 80 | ||||
-rw-r--r-- | source3/lib/util_pwdb.c | 29 | ||||
-rw-r--r-- | source3/nmbd/nmbd.c | 2 | ||||
-rw-r--r-- | source3/rpc_parse/parse_samr.c | 119 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr.c | 118 | ||||
-rw-r--r-- | source3/smbd/server.c | 2 | ||||
-rw-r--r-- | source3/utils/smbpasswd.c | 2 | ||||
-rw-r--r-- | source3/web/swat.c | 2 |
10 files changed, 313 insertions, 74 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index b362940a4c..4360d6b8ee 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -261,6 +261,7 @@ char *rep_inet_ntoa(struct in_addr ip); void get_sam_domain_name(void); BOOL get_member_domain_sid(void); +BOOL get_domain_sids(DOM_SID *sid3, DOM_SID *sid5); void generate_wellknown_sids(void); BOOL generate_sam_sid(char *domain_name); BOOL map_domain_name_to_sid(DOM_SID *sid, char **nt_domain); @@ -457,7 +458,7 @@ void pwdb_set_must_change_time(char *p, int max_len, time_t t); void pwdb_set_last_set_time(char *p, int max_len, time_t t); void pwdb_sethexpwd(char *p, const char *pwd, uint16 acct_ctrl); BOOL pwdb_gethexpwd(const char *p, char *pwd); -BOOL pwdb_initialise(void); +BOOL pwdb_initialise(BOOL server); /*The following definitions come from lib/util_sid.c */ @@ -2112,8 +2113,11 @@ void make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u, POLICY_HND *hnd, DOM_SID *sid); void samr_io_q_add_aliasmem(char *desc, SAMR_Q_ADD_ALIASMEM *q_u, prs_struct *ps, int depth); void samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM *r_u, prs_struct *ps, int depth); -void make_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c, - POLICY_HND *hnd, uint16 unk_1, uint16 unk_2); +void make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_c, POLICY_HND *hnd); +void samr_io_q_query_aliasmem(char *desc, SAMR_Q_QUERY_ALIASMEM *q_u, prs_struct *ps, int depth); +void make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM *r_u, + uint32 num_sids, DOM_SID *sid, uint32 status); +void samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM *r_u, prs_struct *ps, int depth); 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); diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index 6a1dc8d860..f34fe3ed77 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -1145,15 +1145,26 @@ typedef struct r_samr_open_group_info } SAMR_R_OPEN_GROUP; -/* SAMR_Q_UNKNOWN_21 - probably an open group in domain */ -typedef struct q_samr_unknown_21_info +/* SAMR_Q_QUERY_ALIASMEM - query alias members */ +typedef struct q_samr_query_aliasmem_info { - POLICY_HND group_pol; /* policy handle */ + POLICY_HND alias_pol; /* policy handle */ + +} SAMR_Q_QUERY_ALIASMEM; + - uint16 unknown_1; /* 16 bit unknown - 0x0477 */ - uint16 unknown_2; /* 16 bit unknown - 0x0000 */ +/* SAMR_R_QUERY_ALIASMEM - query alias members */ +typedef struct r_samr_query_aliasmem_info +{ + uint32 num_sids; + uint32 ptr; + uint32 num_sids1; + + DOM_SID *sid; + + uint32 status; -} SAMR_Q_UNKNOWN_21; +} SAMR_R_QUERY_ALIASMEM; /* SAMR_Q_UNK_ALIASMEM - don't know! */ diff --git a/source3/lib/sids.c b/source3/lib/sids.c index cd64f1b097..4a2a5d4805 100644 --- a/source3/lib/sids.c +++ b/source3/lib/sids.c @@ -149,19 +149,10 @@ void get_sam_domain_name(void) } /**************************************************************************** - obtain the sid from the PDC. do some verification along the way... + obtain the sid from the PDC. ****************************************************************************/ BOOL get_member_domain_sid(void) { - POLICY_HND pol; - fstring srv_name; - struct cli_state cli; - BOOL res = True; - DOM_SID sid3; - DOM_SID sid5; - fstring dom3; - fstring dom5; - switch (lp_server_role()) { case ROLE_DOMAIN_NONE: @@ -181,6 +172,27 @@ BOOL get_member_domain_sid(void) } } + return get_domain_sids(NULL, &global_member_sid); +} + +/**************************************************************************** + obtain the sid from the PDC. do some verification along the way... +****************************************************************************/ +BOOL get_domain_sids(DOM_SID *sid3, DOM_SID *sid5) +{ + POLICY_HND pol; + fstring srv_name; + struct cli_state cli; + BOOL res = True; + fstring dom3; + fstring dom5; + + if (sid3 == NULL && sid5 == NULL) + { + /* don't waste my time... */ + return False; + } + if (!cli_connect_serverlist(&cli, lp_passwordserver())) { DEBUG(0,("get_member_domain_sid: unable to initialise client connection.\n")); @@ -194,8 +206,14 @@ BOOL get_member_domain_sid(void) fstrcpy(dom3, ""); fstrcpy(dom5, ""); - ZERO_STRUCT(sid3); - ZERO_STRUCT(sid5); + if (sid3 != NULL) + { + ZERO_STRUCTP(sid3); + } + if (sid5 != NULL) + { + ZERO_STRUCTP(sid5); + } fstrcpy(srv_name, "\\\\"); fstrcat(srv_name, global_myname); @@ -207,11 +225,17 @@ BOOL get_member_domain_sid(void) /* lookup domain controller; receive a policy handle */ res = res ? do_lsa_open_policy(&cli, srv_name, &pol, False) : False; - /* send client info query, level 3. receive domain name and sid */ - res = res ? do_lsa_query_info_pol(&cli, &pol, 3, dom3, &sid3) : False; + if (sid3 != NULL) + { + /* send client info query, level 3. receive domain name and sid */ + res = res ? do_lsa_query_info_pol(&cli, &pol, 3, dom3, sid3) : False; + } - /* send client info query, level 5. receive domain name and sid */ - res = res ? do_lsa_query_info_pol(&cli, &pol, 5, dom5, &sid5) : False; + if (sid5 != NULL) + { + /* send client info query, level 5. receive domain name and sid */ + res = res ? do_lsa_query_info_pol(&cli, &pol, 5, dom5, sid5) : False; + } /* close policy handle */ res = res ? do_lsa_close(&cli, &pol) : False; @@ -225,10 +249,16 @@ BOOL get_member_domain_sid(void) { pstring sid; DEBUG(2,("LSA Query Info Policy\n")); - sid_to_string(sid, &sid3); - DEBUG(2,("Domain Member - Domain: %s SID: %s\n", dom3, sid)); - sid_to_string(sid, &sid5); - DEBUG(2,("Domain Controller - Domain: %s SID: %s\n", dom5, sid)); + if (sid3 != NULL) + { + sid_to_string(sid, sid3); + DEBUG(2,("Domain Member - Domain: %s SID: %s\n", dom3, sid)); + } + if (sid5 != NULL) + { + sid_to_string(sid, sid5); + DEBUG(2,("Domain Controller - Domain: %s SID: %s\n", dom5, sid)); + } if (!strequal(dom3, global_myworkgroup) || !strequal(dom5, global_myworkgroup)) @@ -243,16 +273,6 @@ BOOL get_member_domain_sid(void) DEBUG(1,("lsa query info failed\n")); } - if (!res) - { - DEBUG(0,("get_member_domain_sid: unable to obtain Domain member SID\n")); - } - else - { - /* this is a _lot_ of trouble to go to for just this info: */ - global_member_sid = sid5; - } - return res; } diff --git a/source3/lib/util_pwdb.c b/source3/lib/util_pwdb.c index 588070f7b8..8008e9de71 100644 --- a/source3/lib/util_pwdb.c +++ b/source3/lib/util_pwdb.c @@ -26,9 +26,11 @@ extern int DEBUGLEVEL; extern DOM_SID global_sam_sid; extern fstring global_sam_name; -extern DOM_SID global_sid_S_1_5_20; + +extern DOM_SID global_member_sid; extern fstring global_myworkgroup; +extern DOM_SID global_sid_S_1_5_20; /* * A list of the rids of well known BUILTIN and Domain users * and groups. @@ -416,7 +418,7 @@ BOOL pwdb_gethexpwd(const char *p, char *pwd) /************************************************************* initialise password databases, domain names, domain sid. **************************************************************/ -BOOL pwdb_initialise(void) +BOOL pwdb_initialise(BOOL is_server) { fstrcpy(global_myworkgroup, lp_workgroup()); @@ -430,15 +432,22 @@ BOOL pwdb_initialise(void) generate_wellknown_sids(); - if (!generate_sam_sid(global_sam_name)) + if (is_server) { - DEBUG(0,("ERROR: Samba cannot create a SAM SID for its domain (%s).\n", - global_sam_name)); - return False; + if (!generate_sam_sid(global_sam_name)) + { + DEBUG(0,("ERROR: Samba cannot create a SAM SID for its domain (%s).\n", + global_sam_name)); + return False; + } + } + else + { + if (!get_domain_sids(&global_member_sid, &global_sam_sid)) + { + return False; + } } - if(!initialise_password_db()) - return False; - - return True; + return initialise_password_db(); } diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index bfcf0ad239..46c24aee7d 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -677,7 +677,7 @@ static void usage(char *pname) reload_services( True ); - if (!pwdb_initialise()) + if (!pwdb_initialise(True)) { exit(1); } diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index f6e0fa642f..4fdcf19577 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -1588,20 +1588,20 @@ void make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u, r_u->gid = gid; } else - { + { r_u->ptr_0 = 0; r_u->num_entries = 0; r_u->ptr_1 = 0; } r_u->status = status; - } +} /******************************************************************* reads or writes a structure. ********************************************************************/ void samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth) - { +{ int i; if (r_u == NULL) return; @@ -1626,10 +1626,10 @@ void samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_s prs_grow(ps); smb_io_gid("", &(r_u->gid[i]), ps, depth); } - } } - prs_uint32("status", ps, depth, &(r_u->status)); } + prs_uint32("status", ps, depth, &(r_u->status)); +} /******************************************************************* @@ -2342,7 +2342,7 @@ makes a SAMR_Q_CREATE_DOM_ALIAS structure. ********************************************************************/ void make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u, POLICY_HND *hnd, char *acct_desc) - { +{ int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0; if (q_u == NULL) return; @@ -2428,13 +2428,13 @@ void samr_io_q_unk_aliasmem(char *desc, SAMR_Q_UNK_ALIASMEM *q_u, prs_struct *p smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth); smb_io_dom_sid("sid ", &(q_u->sid ), ps, depth); - } +} /******************************************************************* reads or writes a structure. ********************************************************************/ void samr_io_r_unk_aliasmem(char *desc, SAMR_R_UNK_ALIASMEM *r_u, prs_struct *ps, int depth) - { +{ if (r_u == NULL) return; prs_debug(ps, depth, desc, "samr_io_r_unk_aliasmem"); @@ -2465,7 +2465,7 @@ void make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u, POLICY_HND *hnd, reads or writes a structure. ********************************************************************/ void samr_io_q_add_aliasmem(char *desc, SAMR_Q_ADD_ALIASMEM *q_u, prs_struct *ps, int depth) - { +{ if (q_u == NULL) return; prs_debug(ps, depth, desc, "samr_io_q_add_aliasmem"); @@ -2493,20 +2493,105 @@ void samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM *r_u, prs_struct *p } /******************************************************************* -makes a SAMR_Q_UNKNOWN_21 structure. +makes a SAMR_Q_QUERY_ALIASMEM structure. ********************************************************************/ -void make_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c, - POLICY_HND *hnd, uint16 unk_1, uint16 unk_2) - { +void make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_c, POLICY_HND *hnd) +{ if (q_c == NULL || hnd == NULL) return; - DEBUG(5,("make_samr_q_unknown_21\n")); + DEBUG(5,("make_samr_q_query_aliasmem\n")); + + memcpy(&(q_c->alias_pol), hnd, sizeof(q_c->alias_pol)); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void samr_io_q_query_aliasmem(char *desc, SAMR_Q_QUERY_ALIASMEM *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_q_query_aliasmem"); + depth++; + + prs_align(ps); - memcpy(&(q_c->group_pol), hnd, sizeof(q_c->group_pol)); - q_c->unknown_1 = unk_1; - q_c->unknown_2 = unk_2; + smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth); +} + +/******************************************************************* +makes a SAMR_R_QUERY_ALIASMEM structure. +********************************************************************/ +void make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM *r_u, + uint32 num_sids, DOM_SID *sid, uint32 status) +{ + if (r_u == NULL) return; + + DEBUG(5,("make_samr_r_query_aliasmem\n")); + + if (status == 0x0) + { + r_u->num_sids = num_sids; + r_u->ptr = (num_sids != 0) ? 1 : 0; + r_u->num_sids = num_sids; + + r_u->sid = sid; + } + else + { + r_u->ptr = 0; + r_u->num_sids = 0; } + r_u->status = status; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM *r_u, prs_struct *ps, int depth) +{ + int i; + uint32 ptr_sid[MAX_LOOKUP_SIDS]; + + if (r_u == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_r_query_aliasmem"); + depth++; + + prs_align(ps); + + prs_uint32("ptr", ps, depth, &(r_u->ptr)); + + if (r_u->ptr != 0) + { + prs_uint32("num_sids ", ps, depth, &(r_u->num_sids)); + + SMB_ASSERT_ARRAY(ptr_sid, r_u->num_sids); + + if (r_u->num_sids != 0) + { + prs_uint32("num_sids1", ps, depth, &(r_u->num_sids1)); + + for (i = 0; i < r_u->num_sids1; i++) + { + prs_grow(ps); + ptr_sid[i] = 1; + prs_uint32("", ps, depth, &(ptr_sid[i])); + } + for (i = 0; i < r_u->num_sids1; i++) + { + prs_grow(ps); + if (ptr_sid[i] != 0) + { + smb_io_dom_sid("", &(r_u->sid[i]), ps, depth); + } + } + } + } + prs_uint32("status", ps, depth, &(r_u->status)); +} + /******************************************************************* reads or writes a structure. diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index 45095a9c3b..0ba7d0871e 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -695,14 +695,14 @@ static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u, { if (q_u->switch_level == 3) { - status = NT_STATUS_INVALID_INFO_CLASS; - } - else - { r_e.ptr = 1; ctr.switch_value = 3; make_samr_alias_info3(&ctr.alias.info3, "<account description>"); } + else + { + status = NT_STATUS_INVALID_INFO_CLASS; + } } make_samr_r_query_aliasinfo(&r_e, status == 0 ? &ctr : NULL, status); @@ -854,6 +854,104 @@ static void api_samr_query_useraliases( uint16 vuid, prs_struct *data, prs_struc } /******************************************************************* + samr_reply_query_aliasmem + ********************************************************************/ +static void samr_reply_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_u, + prs_struct *rdata) +{ + uint32 status = 0; + + LOCAL_GRP_MEMBER *mem_grp = NULL; + DOM_SID *sid = NULL; + int num_sids = 0; + DOM_SID alias_sid; + uint32 alias_rid; + fstring alias_sid_str; + + SAMR_R_QUERY_ALIASMEM r_u; + + DEBUG(5,("samr_query_aliasmem: %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_sid_S_1_5_20)) + { + DEBUG(10,("lookup on S-1-5-20\n")); + + become_root(True); + status = getbuiltinrid(alias_rid, &mem_grp, &num_sids) ? 0xC0000000 | NT_STATUS_NO_SUCH_GROUP : 0x0; + unbecome_root(True); + } + else if (sid_equal(&alias_sid, &global_sam_sid)) + { + DEBUG(10,("lookup on Domain SID\n")); + + become_root(True); + status = getaliasrid(alias_rid, &mem_grp, &num_sids) ? 0xC0000000 | NT_STATUS_NO_SUCH_GROUP : 0x0; + unbecome_root(True); + } + else + { + status = 0xC0000000 | NT_STATUS_NO_SUCH_USER; + } + } + + if (status == 0x0 && num_sids > 0) + { + sid = malloc(num_sids * sizeof(DOM_SID)); + if (mem_grp != NULL && sid != NULL) + { + int i; + for (i = 0; i < num_sids; i++) + { + sid[i] = mem_grp[i].sid; + } + free(mem_grp); + } + } + + make_samr_r_query_aliasmem(&r_u, num_sids, sid, status); + + /* store the response in the SMB stream */ + samr_io_r_query_aliasmem("", &r_u, rdata, 0); + + if (sid != NULL) + { + free(sid); + } + + DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__)); + +} + +/******************************************************************* + api_samr_query_aliasmem + ********************************************************************/ +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); +} + +/******************************************************************* samr_reply_lookup_names ********************************************************************/ static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u, @@ -1669,6 +1767,7 @@ static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata) { SAMR_R_OPEN_ALIAS r_u; + DOM_SID sid; BOOL pol_open = False; /* set up the SAMR open_alias response */ @@ -1687,6 +1786,16 @@ static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND; } + sid_copy(&sid, &global_sid_S_1_5_20); + sid_append_rid(&sid, q_u->rid_alias); + + /* associate an alias SID with the (unique) handle. */ + if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.pol), &sid)) + { + /* oh, whoops. don't know what error message to return, here */ + r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + if (r_u.status != 0 && pol_open) { close_lsa_policy_hnd(&(r_u.pol)); @@ -1728,6 +1837,7 @@ static struct api_struct api_samr_cmds [] = { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups }, { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases }, { "SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES, api_samr_query_useraliases}, + { "SAMR_QUERY_ALIASMEM" , SAMR_QUERY_ALIASMEM , api_samr_query_aliasmem }, { "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/smbd/server.c b/source3/smbd/server.c index 7a16d8abf3..3e25bfa633 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -651,7 +651,7 @@ static void usage(char *pname) codepage_initialise(lp_client_code_page()); - if (!pwdb_initialise()) + if (!pwdb_initialise(True)) { exit(1); } diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index a5756dd797..722ff6f8b2 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -574,7 +574,7 @@ int main(int argc, char **argv) codepage_initialise(lp_client_code_page()); - if(!pwdb_initialise()) + if(!pwdb_initialise(False)) { fprintf(stderr, "Can't setup password database vectors.\n"); exit(1); diff --git a/source3/web/swat.c b/source3/web/swat.c index c4baa70e0b..3383b29f3b 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -600,7 +600,7 @@ static BOOL change_password(const char *remote_machine, char *user_name, return ret; } - if (!pwdb_initialise()) + if (!pwdb_initialise(False)) { printf("Can't setup password database vectors.\n<p>"); return False; |