From a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 15 Oct 1998 05:47:29 +0000 Subject: bug-fixing against: AS/U: it returns dce/rpc "first" and "last" bits _clear_ in a bind/ack response, when they should be set in a (small) packet. they also, in the bind/ack do not set a secondary address string at all, so we can't check against that... Win95: client-side dce/rpc code is a bit odd. it does a "WaitNamedPipeState" and has slightly different pipe-naming (\PIPE\LANMAN is joined by \PIPE\SRVSVC, \PIPE\WINREG etc whereas nt just has \PIPE\LANMAN and \PIPE\). Win95-USRMGR.EXE: added LsaOpenPolicy (renamed existing to LsaOpenPolicy2). added SamrConnect (renamed existing to SamrConnect2). (This used to be commit a7fccd807b938cbb51002ebae8c7a48b40dbb655) --- source3/include/client.h | 2 + source3/include/ntdomain.h | 1 + source3/include/proto.h | 15 ++++- source3/include/rpc_lsa.h | 28 ++++++++-- source3/include/rpc_samr.h | 28 ++++++++-- source3/lsarpcd/srv_lsa.c | 42 ++++++++++++++ source3/passdb/smbpass.c | 2 + source3/rpc_client/cli_pipe.c | 26 +++++++-- source3/rpc_client/cli_samr.c | 3 +- source3/rpc_parse/parse_lsa.c | 67 +++++++++++++++++++++- source3/rpc_parse/parse_samr.c | 73 +++++++++++++++++++++--- source3/rpc_server/srv_lsa.c | 42 ++++++++++++++ source3/rpc_server/srv_pipe_hnd.c | 24 ++++++++ source3/rpc_server/srv_samr.c | 115 +++++++++++++++++++++++++++++--------- source3/smbd/ipc.c | 41 +++++++++++++- 15 files changed, 454 insertions(+), 55 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index 53674fe80a..a393ee25a8 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -126,6 +126,8 @@ struct cli_state { fstring mach_acct; /* MYNAME$. */ fstring srv_name_slash; /* \\remote server. */ fstring clnt_name_slash; /* \\local client. */ + uint16 max_xmit_frag; + uint16 max_recv_frag; }; #endif /* _CLIENT_H */ diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index c2a4170595..e540bd2ffc 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -61,6 +61,7 @@ typedef struct pipes_struct uint16 vuid; BOOL open; /* open connection */ uint16 device_state; + uint16 priority; fstring name; fstring pipe_srv_name; diff --git a/source3/include/proto.h b/source3/include/proto.h index 5e47faf5ef..411f923ba8 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1339,12 +1339,18 @@ void make_lsa_trans_name(LSA_TRANS_NAME *trn, uint32 sid_name_use, char *name, u void make_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff, uint32 unknown); void make_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos); -void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name, +void make_q_open_pol(LSA_Q_OPEN_POL *r_q, uint16 system_name, uint32 attributes, uint32 desired_access, LSA_SEC_QOS *qos); void lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth); void lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth); +void make_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, char *server_name, + uint32 attributes, + uint32 desired_access, + LSA_SEC_QOS *qos); +void lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, int depth); +void lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 *r_p, prs_struct *ps, int depth); void make_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class); void lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth); void lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth); @@ -1710,6 +1716,9 @@ void make_samr_q_connect(SAMR_Q_CONNECT *q_u, char *srv_name, uint32 unknown_0); void samr_io_q_connect(char *desc, SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth); void samr_io_r_connect(char *desc, SAMR_R_CONNECT *r_u, prs_struct *ps, int depth); +void make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u); +void samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth); +void samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth); void make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u, uint32 unknown_0, uint32 rid); void samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth); @@ -1723,8 +1732,7 @@ void make_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c, POLICY_HND *hnd, uint16 unk_1, uint16 unk_2); void make_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name); void samr_io_q_unknown_38(char *desc, SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth); -void make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u, - uint16 level, uint32 status); +void make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u); void samr_io_r_unknown_38(char *desc, SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth); void make_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512]); void samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth); @@ -1860,6 +1868,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name, connection_struct *conn, uint16 vuid); int write_pipe(pipes_struct *p, char *data, int n); int read_pipe(pipes_struct *p, char *data, uint32 pos, int n); +BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority); BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state); BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn); pipes_struct *get_rpc_pipe_p(char *buf, int where); diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index fe4d018dbb..44758936ae 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -39,7 +39,8 @@ enum SID_NAME_USE #define LSA_ENUMTRUSTDOM 0x0d #define LSA_LOOKUPNAMES 0x0e #define LSA_LOOKUPSIDS 0x0f -#define LSA_OPENPOLICY 0x2c +#define LSA_OPENPOLICY 0x06 +#define LSA_OPENPOLICY2 0x2c #define LSA_OPENSECRET 0x1C /* XXXX these are here to get a compile! */ @@ -89,9 +90,9 @@ typedef struct obj_attr_info /* LSA_Q_OPEN_POL - LSA Query Open Policy */ typedef struct lsa_q_open_pol_info { - uint32 ptr; /* undocumented buffer pointer */ - UNISTR2 uni_server_name; /* server name, starting with two '\'s */ - LSA_OBJ_ATTR attr ; /* object attributes */ + uint32 ptr; /* undocumented buffer pointer */ + uint16 system_name; /* 0x5c - system name */ + LSA_OBJ_ATTR attr ; /* object attributes */ uint32 des_access; /* desired access attributes */ @@ -105,6 +106,25 @@ typedef struct lsa_r_open_pol_info } LSA_R_OPEN_POL; +/* LSA_Q_OPEN_POL2 - LSA Query Open Policy */ +typedef struct lsa_q_open_pol2_info +{ + uint32 ptr; /* undocumented buffer pointer */ + UNISTR2 uni_server_name; /* server name, starting with two '\'s */ + LSA_OBJ_ATTR attr ; /* object attributes */ + + uint32 des_access; /* desired access attributes */ + +} LSA_Q_OPEN_POL2; + +/* LSA_R_OPEN_POL2 - response to LSA Open Policy */ +typedef struct lsa_r_open_pol2_info +{ + POLICY_HND pol; /* policy handle */ + uint32 status; /* return code */ + +} LSA_R_OPEN_POL2; + /* LSA_Q_QUERY_INFO - LSA query info policy */ typedef struct lsa_query_info { diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index f27dc66381..baae9a3bd9 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -94,6 +94,7 @@ SamrTestPrivateFunctionsUser #define SAMR_CHGPASSWD_USER 0x37 #define SAMR_UNKNOWN_38 0x38 #define SAMR_CONNECT 0x39 +#define SAMR_CONNECT_ANON 0x00 #define SAMR_OPEN_ALIAS 0x1b #define SAMR_QUERY_ALIASINFO 0x1c #define SAMR_ENUM_DOM_USERS 0x0d @@ -934,12 +935,30 @@ typedef struct q_samr_open_alias_info /* SAMR_R_OPEN_ALIAS - probably an open */ typedef struct r_samr_open_alias_info { - POLICY_HND pol; /* policy handle */ + POLICY_HND pol; /* policy handle */ uint32 status; /* return status */ } SAMR_R_OPEN_ALIAS; +/* SAMR_Q_CONNECT_ANON - probably an open */ +typedef struct q_samr_connect_anon_info +{ + uint32 ptr; /* ptr? */ + uint16 unknown_0; /* 0x005c */ + uint16 unknown_1; /* 0x0001 */ + uint32 unknown_2; /* 0x0000 0020 */ + +} SAMR_Q_CONNECT_ANON; + +/* SAMR_R_CONNECT_ANON - probably an open */ +typedef struct r_samr_connect_anon_info +{ + POLICY_HND connect_pol; /* policy handle */ + uint32 status; /* return status */ + +} SAMR_R_CONNECT_ANON; + /* SAMR_Q_CONNECT - probably an open */ typedef struct q_samr_connect_info { @@ -971,9 +990,10 @@ typedef struct q_samr_unknown_38 /* SAMR_R_UNKNOWN_38 */ typedef struct r_samr_unknown_38 { - LOOKUP_LEVEL level; /* 0x0006 */ - uint32 ptr_0; /* 0x0000 0000 */ - uint32 status; + uint16 unk_0; + uint16 unk_1; + uint16 unk_2; + uint16 unk_3; } SAMR_R_UNKNOWN_38; diff --git a/source3/lsarpcd/srv_lsa.c b/source3/lsarpcd/srv_lsa.c index 2e5ebc9e68..93584b5acf 100644 --- a/source3/lsarpcd/srv_lsa.c +++ b/source3/lsarpcd/srv_lsa.c @@ -30,6 +30,28 @@ extern int DEBUGLEVEL; extern DOM_SID global_machine_sid; +/*************************************************************************** +lsa_reply_open_policy2 + ***************************************************************************/ +static void lsa_reply_open_policy2(prs_struct *rdata) +{ + int i; + LSA_R_OPEN_POL2 r_o; + + ZERO_STRUCT(r_o); + + /* set up the LSA QUERY INFO response */ + + for (i = 4; i < POL_HND_SIZE; i++) + { + r_o.pol.data[i] = i; + } + r_o.status = 0x0; + + /* store the response in the SMB stream */ + lsa_io_r_open_pol2("", &r_o, rdata, 0); +} + /*************************************************************************** lsa_reply_open_policy ***************************************************************************/ @@ -279,6 +301,25 @@ static void lsa_reply_lookup_rids(prs_struct *rdata, lsa_io_r_lookup_rids("", &r_l, rdata, 0); } +/*************************************************************************** +api_lsa_open_policy + ***************************************************************************/ +static void api_lsa_open_policy2( uint16 vuid, prs_struct *data, + prs_struct *rdata ) +{ + LSA_Q_OPEN_POL2 q_o; + + ZERO_STRUCT(q_o); + + /* grab the server, object attributes and desired access flag...*/ + lsa_io_q_open_pol2("", &q_o, data, 0); + + /* lkclXXXX having decoded it, ignore all fields in the open policy! */ + + /* return a 20 byte policy handle */ + lsa_reply_open_policy2(rdata); +} + /*************************************************************************** api_lsa_open_policy ***************************************************************************/ @@ -513,6 +554,7 @@ static void api_lsa_open_secret( uint16 vuid, prs_struct *data, ***************************************************************************/ static struct api_struct api_lsa_cmds[] = { + { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 }, { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy }, { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info }, { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom }, diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c index 35de214425..085ece0f5e 100644 --- a/source3/passdb/smbpass.c +++ b/source3/passdb/smbpass.c @@ -323,6 +323,8 @@ static struct sam_passwd *getsmbfile21pwent(void *vp) static pstring acct_desc; static pstring workstations; + DEBUG(5,("getsmbfile21pwent\n")); + if (pw_buf == NULL) return NULL; pwfile = getpwnam(pw_buf->smb_name); diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 405b6abe66..4ea38fa828 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -51,7 +51,7 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_read, uint32 rdata_offset) { - int size = 0x1630; + int size = cli->max_recv_frag; int file_offset = rdata_offset; int num_read; char *data = rdata->data->data; @@ -249,6 +249,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, setup[0] = cmd; setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ + DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", cmd, cli->nt_pipe_fnum)); + /* send the data: receive a response. */ if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, setup, 2, 0, /* Setup, length, max */ @@ -278,6 +280,16 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, return False; } + if (rhdr.pkt_type == RPC_BINDACK) + { + if (!last && !first) + { + DEBUG(5,("rpc_api_pipe: bug in AS/U, setting fragment first/last ON\n")); + first = True; + last = True; + } + } + if (rhdr.pkt_type == RPC_RESPONSE) { RPC_HDR_RESP rhdr_resp; @@ -731,7 +743,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * { int i = 0; - while ((pipe_names[i].client_pipe != NULL)) + while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0) { DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n", pipe_names[i].client_pipe , pipe_names[i].server_pipe )); @@ -746,10 +758,10 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * } else { - DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n", + DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n", pipe_names[i].server_pipe , hdr_ba->addr.str)); - return False; + break; } } else @@ -853,6 +865,12 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer); } + if (valid_ack) + { + cli->max_xmit_frag = hdr_ba.bba.max_tsize; + cli->max_recv_frag = hdr_ba.bba.max_rsize; + } + if (valid_ack && ntlmssp_auth) { smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0); diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 9fe4c0a16a..fae96b561c 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -186,13 +186,14 @@ BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name) samr_io_r_unknown_38("", &r_e, &rdata, 0); p = rdata.offset != 0; +#if 0 if (p && r_e.status != 0) { /* report error code */ DEBUG(0,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status))); p = False; } - +#endif if (p) { valid_un8 = True; diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 40f05e0c3a..49a0951554 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -227,10 +227,11 @@ static void lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR *attr, prs_struct *ps, int } } + /******************************************************************* makes an LSA_Q_OPEN_POL structure. ********************************************************************/ -void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name, +void make_q_open_pol(LSA_Q_OPEN_POL *r_q, uint16 system_name, uint32 attributes, uint32 desired_access, LSA_SEC_QOS *qos) @@ -246,7 +247,7 @@ void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name, r_q->des_access = desired_access; } - make_unistr2 (&(r_q->uni_server_name), server_name, strlen(server_name)); + r_q->system_name = system_name; make_lsa_obj_attr(&(r_q->attr ), attributes, qos); } @@ -261,8 +262,9 @@ void lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int dep depth++; prs_uint32("ptr ", ps, depth, &(r_q->ptr )); + prs_uint16("system_name", ps, depth, &(r_q->system_name )); + prs_align ( ps ); - smb_io_unistr2 ("", &(r_q->uni_server_name), r_q->ptr, ps, depth); lsa_io_obj_attr("", &(r_q->attr ), ps, depth); if (r_q->attr.ptr_sec_qos == 0) @@ -286,6 +288,65 @@ void lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int dep prs_uint32("status", ps, depth, &(r_p->status)); } +/******************************************************************* +makes an LSA_Q_OPEN_POL2 structure. +********************************************************************/ +void make_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, char *server_name, + uint32 attributes, + uint32 desired_access, + LSA_SEC_QOS *qos) +{ + if (r_q == NULL) return; + + DEBUG(5,("make_open_pol2: attr:%d da:%d\n", attributes, desired_access)); + + r_q->ptr = 1; /* undocumented pointer */ + + if (qos == NULL) + { + r_q->des_access = desired_access; + } + + make_unistr2 (&(r_q->uni_server_name), server_name, strlen(server_name)); + make_lsa_obj_attr(&(r_q->attr ), attributes, qos); +} + +/******************************************************************* +reads or writes an LSA_Q_OPEN_POL2 structure. +********************************************************************/ +void lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "lsa_io_q_open_pol2"); + depth++; + + prs_uint32("ptr ", ps, depth, &(r_q->ptr )); + + smb_io_unistr2 ("", &(r_q->uni_server_name), r_q->ptr, ps, depth); + lsa_io_obj_attr("", &(r_q->attr ), ps, depth); + + if (r_q->attr.ptr_sec_qos == 0) + { + prs_uint32("des_access", ps, depth, &(r_q->des_access)); + } +} + +/******************************************************************* +reads or writes an LSA_R_OPEN_POL2 structure. +********************************************************************/ +void lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 *r_p, prs_struct *ps, int depth) +{ + if (r_p == NULL) return; + + prs_debug(ps, depth, desc, "lsa_io_r_open_pol2"); + depth++; + + smb_io_pol_hnd("", &(r_p->pol), ps, depth); + + prs_uint32("status", ps, depth, &(r_p->status)); +} + /******************************************************************* makes an LSA_Q_QUERY_INFO structure. ********************************************************************/ diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index b71c209845..eb882a7564 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -2402,6 +2402,58 @@ void samr_io_r_connect(char *desc, SAMR_R_CONNECT *r_u, prs_struct *ps, int dep prs_uint32("status", ps, depth, &(r_u->status)); } +/******************************************************************* +makes a SAMR_Q_CONNECT_ANON structure. +********************************************************************/ +void make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u) +{ + if (q_u == NULL) return; + + DEBUG(5,("make_q_connect_anon\n")); + + q_u->ptr = 1; + q_u->unknown_0 = 0x5c; + q_u->unknown_1 = 0x01; + q_u->unknown_2 = 0x20; +} + + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_q_connect_anon"); + depth++; + + prs_align(ps); + + prs_uint32("ptr ", ps, depth, &(q_u->ptr )); + prs_uint16("unknown_0", ps, depth, &(q_u->unknown_0)); + prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1)); + prs_uint32("unknown_2", ps, depth, &(q_u->unknown_2)); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth) +{ + if (r_u == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_r_connect_anon"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("connect_pol", &(r_u->connect_pol), ps, depth); + prs_align(ps); + + prs_uint32("status", ps, depth, &(r_u->status)); +} + /******************************************************************* makes a SAMR_Q_OPEN_ALIAS structure. ********************************************************************/ @@ -2552,16 +2604,16 @@ void samr_io_q_unknown_38(char *desc, SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, i /******************************************************************* makes a SAMR_R_UNKNOWN_38 structure. ********************************************************************/ -void make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u, - uint16 level, uint32 status) +void make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u) { if (r_u == NULL) return; DEBUG(5,("make_r_unknown_38\n")); - r_u->level.value = level; - r_u->ptr_0 = 0; - r_u->status = status; + r_u->unk_0 = 0; + r_u->unk_1 = 0; + r_u->unk_2 = 0; + r_u->unk_3 = 0; } /******************************************************************* @@ -2576,9 +2628,14 @@ void samr_io_r_unknown_38(char *desc, SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, i prs_align(ps); - smb_io_lookup_level("level ", &(r_u->level), ps, depth); - prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0 )); - prs_uint32("status", ps, depth, &(r_u->status)); + prs_uint16("unk_0", ps, depth, &(r_u->unk_0)); + prs_align(ps); + prs_uint16("unk_1", ps, depth, &(r_u->unk_1)); + prs_align(ps); + prs_uint16("unk_2", ps, depth, &(r_u->unk_2)); + prs_align(ps); + prs_uint16("unk_3", ps, depth, &(r_u->unk_3)); + prs_align(ps); } /******************************************************************* diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c index 2e5ebc9e68..93584b5acf 100644 --- a/source3/rpc_server/srv_lsa.c +++ b/source3/rpc_server/srv_lsa.c @@ -30,6 +30,28 @@ extern int DEBUGLEVEL; extern DOM_SID global_machine_sid; +/*************************************************************************** +lsa_reply_open_policy2 + ***************************************************************************/ +static void lsa_reply_open_policy2(prs_struct *rdata) +{ + int i; + LSA_R_OPEN_POL2 r_o; + + ZERO_STRUCT(r_o); + + /* set up the LSA QUERY INFO response */ + + for (i = 4; i < POL_HND_SIZE; i++) + { + r_o.pol.data[i] = i; + } + r_o.status = 0x0; + + /* store the response in the SMB stream */ + lsa_io_r_open_pol2("", &r_o, rdata, 0); +} + /*************************************************************************** lsa_reply_open_policy ***************************************************************************/ @@ -279,6 +301,25 @@ static void lsa_reply_lookup_rids(prs_struct *rdata, lsa_io_r_lookup_rids("", &r_l, rdata, 0); } +/*************************************************************************** +api_lsa_open_policy + ***************************************************************************/ +static void api_lsa_open_policy2( uint16 vuid, prs_struct *data, + prs_struct *rdata ) +{ + LSA_Q_OPEN_POL2 q_o; + + ZERO_STRUCT(q_o); + + /* grab the server, object attributes and desired access flag...*/ + lsa_io_q_open_pol2("", &q_o, data, 0); + + /* lkclXXXX having decoded it, ignore all fields in the open policy! */ + + /* return a 20 byte policy handle */ + lsa_reply_open_policy2(rdata); +} + /*************************************************************************** api_lsa_open_policy ***************************************************************************/ @@ -513,6 +554,7 @@ static void api_lsa_open_secret( uint16 vuid, prs_struct *data, ***************************************************************************/ static struct api_struct api_lsa_cmds[] = { + { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 }, { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy }, { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info }, { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom }, diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 4d5fd3865e..b1aede6166 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -123,6 +123,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name, p->open = True; p->device_state = 0; + p->priority = 0; p->conn = conn; p->vuid = vuid; @@ -300,6 +301,29 @@ int read_pipe(pipes_struct *p, char *data, uint32 pos, int n) } +/**************************************************************************** + wait device state on a pipe. exactly what this is for is unknown... +****************************************************************************/ +BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority) +{ + if (p == NULL) return False; + + if (p->open) + { + DEBUG(3,("%s Setting pipe wait state priority=%x on pipe (name=%s)\n", + timestring(), priority, p->name)); + + p->priority = priority; + + return True; + } + + DEBUG(3,("%s Error setting pipe wait state priority=%x (name=%s)\n", + timestring(), priority, p->name)); + return False; +} + + /**************************************************************************** set device state on a pipe. exactly what this is for is unknown... ****************************************************************************/ diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index 22827f9f5c..11574be9b3 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -78,7 +78,8 @@ static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl; DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x", - (*num_entries), pwd->smb_name, pwd->user_rid, pwd->acct_ctrl)); + (*num_entries), pwd->smb_name, + pwd->user_rid, pwd->acct_ctrl)); if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask)) { @@ -451,49 +452,55 @@ static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, SAM_INFO_1 info1; SAM_INFO_2 info2; SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]; - int num_entries; - int total_entries; + int num_entries = 0; + int total_entries = 0; BOOL got_pwds; uint16 switch_level = 0x0; + ZERO_STRUCT(r_e); + r_e.status = 0x0; + DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__)); + /* find the policy handle. open a policy on it. */ if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1)) { r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE; + DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n")); } - DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__)); - - become_root(True); - got_pwds = get_sampwd_entries(pass, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0); - unbecome_root(True); - - switch (q_u->switch_level) + if (r_e.status == 0x0) { - case 0x1: + become_root(True); + got_pwds = get_sampwd_entries(pass, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0); + unbecome_root(True); + + switch (q_u->switch_level) { - - /* query disp info is for users */ - switch_level = 0x1; - make_sam_info_1(&info1, ACB_NORMAL, - q_u->start_idx, num_entries, pass); + case 0x1: + { + + /* query disp info is for users */ + switch_level = 0x1; + make_sam_info_1(&info1, ACB_NORMAL, + q_u->start_idx, num_entries, pass); - ctr.sam.info1 = &info1; + ctr.sam.info1 = &info1; - break; - } - case 0x2: - { - /* query disp info is for servers */ - switch_level = 0x2; - make_sam_info_2(&info2, ACB_WSTRUST, - q_u->start_idx, num_entries, pass); + break; + } + case 0x2: + { + /* query disp info is for servers */ + switch_level = 0x2; + make_sam_info_2(&info2, ACB_WSTRUST, + q_u->start_idx, num_entries, pass); - ctr.sam.info2 = &info2; + ctr.sam.info2 = &info2; - break; + break; + } } } @@ -1169,6 +1176,59 @@ static void api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdat } +/******************************************************************* + samr_reply_connect_anon + ********************************************************************/ +static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, + prs_struct *rdata) +{ + SAMR_R_CONNECT_ANON r_u; + BOOL pol_open = False; + + /* set up the SAMR connect_anon response */ + + r_u.status = 0x0; + /* get a (unique) handle. open a policy on it. */ + if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol)))) + { + r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + /* associate the domain SID with the (unique) handle. */ + if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0)) + { + /* 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.connect_pol)); + } + + DEBUG(5,("samr_connect_anon: %d\n", __LINE__)); + + /* store the response in the SMB stream */ + samr_io_r_connect_anon("", &r_u, rdata, 0); + + DEBUG(5,("samr_connect_anon: %d\n", __LINE__)); + +} + +/******************************************************************* + api_samr_connect_anon + ********************************************************************/ +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); +} + /******************************************************************* samr_reply_connect ********************************************************************/ @@ -1283,6 +1343,7 @@ static struct api_struct api_samr_cmds [] = { { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd }, { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect }, + { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon }, { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users }, { "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 }, diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 646ac83331..bfd618f325 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -3124,6 +3124,29 @@ static void api_rpc_trans_reply(char *outbuf, } } +/**************************************************************************** + WaitNamedPipeHandleState +****************************************************************************/ +static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param) +{ + uint16 priority; + + if (!param) return False; + + priority = param[0] + (param[1] << 8); + DEBUG(4,("WaitNamedPipeHandleState priority %x\n", priority)); + + if (wait_rpc_pipe_hnd_state(p, priority)) + { + /* now send the reply */ + send_trans_reply(outbuf, NULL, NULL, NULL, 0, p->file_offset); + + return True; + } + return False; +} + + /**************************************************************************** SetNamedPipeHandleState ****************************************************************************/ @@ -3134,7 +3157,7 @@ static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param) if (!param) return False; id = param[0] + (param[1] << 8); - DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n", id)); + DEBUG(4,("SetNamedPipeHandleState to code %x\n", id)); if (set_rpc_pipe_hnd_state(p, id)) { @@ -3237,6 +3260,12 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf, } break; } + case 0x53: + { + /* Wait Named Pipe Handle state */ + reply = api_WNPHS(outbuf, p, params); + break; + } case 0x01: { /* Set Named Pipe Handle state */ @@ -3434,6 +3463,16 @@ static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *na return api_reply(conn,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt); } + if (strequal(name,"WKSSVC") || + strequal(name,"SRVSVC") || + strequal(name,"WINREG") || + strequal(name,"SAMR") || + strequal(name,"LSARPC")) + { + DEBUG(4,("named pipe command from Win95 (wow!)\n")); + return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt); + } + if (strlen(name) < 1) { return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt); -- cgit