diff options
-rw-r--r-- | source3/include/proto.h | 5 | ||||
-rw-r--r-- | source3/include/smb.h | 4 | ||||
-rw-r--r-- | source3/lsaparse.c | 2 | ||||
-rw-r--r-- | source3/param/loadparm.c | 4 | ||||
-rw-r--r-- | source3/smbd/pipes.c | 140 |
5 files changed, 150 insertions, 5 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 8f8ec5aa8a..fab69de3d1 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -152,6 +152,7 @@ char *lp_socket_address(void); char *lp_nis_home_map_name(void); char *lp_announce_version(void); char *lp_netbios_aliases(void); +char *lp_domainsid(void); BOOL lp_dns_proxy(void); BOOL lp_wins_support(void); BOOL lp_wins_proxy(void); @@ -928,7 +929,7 @@ BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups); char *StrCpy(char *dest,char *src); char *StrnCpy(char *dest,char *src,int n); void putip(void *dest,void *src); -int name_mangle(char *In,char *Out,char name_type); +int name_mangle( char *In, char *Out, char name_type ); BOOL file_exist(char *fname,struct stat *sbuf); time_t file_modtime(char *fname); BOOL directory_exist(char *dname,struct stat *st); @@ -989,7 +990,7 @@ BOOL receive_message_or_smb(int smbfd, int oplock_fd, BOOL send_smb(int fd,char *buffer); char *name_ptr(char *buf,int ofs); int name_extract(char *buf,int ofs,char *name); -int name_len(char *s); +int name_len( char *s ); BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type); void msleep(int t); BOOL in_list(char *s,char *list,BOOL casesensitive); diff --git a/source3/include/smb.h b/source3/include/smb.h index c347202743..9f5279fca0 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -326,6 +326,7 @@ typedef struct domsid2_info { uint32 type; /* value is 5 */ uint32 undoc; /* value is 0 */ + UNIHDR2 hdr; /* XXXX conflict between hdr and str for length */ UNISTR str; /* XXXX conflict between hdr and str for length */ @@ -488,7 +489,8 @@ typedef struct lsa_r_open_pol_info /* LSA_Q_QUERY_INFO - LSA query info policy */ typedef struct lsa_query_info { - uint16 info_class; /* info class (also a policy handle?) */ + LSA_POL_HND pol; /* policy handle */ + uint16 info_class; /* info class */ } LSA_Q_QUERY_INFO; diff --git a/source3/lsaparse.c b/source3/lsaparse.c index 4b5c4f586a..9ea6f566b2 100644 --- a/source3/lsaparse.c +++ b/source3/lsaparse.c @@ -45,6 +45,8 @@ char* lsa_io_q_query(BOOL io, LSA_Q_QUERY_INFO *q_q, char *q, char *base, int al { if (q_q == NULL) return NULL; + q = smb_io_pol_hnd(io, &(q_q->pol), q, base, align); + RW_SVAL(io, q, q_q->info_class, 0); q += 2; return q; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index fb656aa627..edc2d2b65f 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -140,6 +140,7 @@ typedef struct char *szNISHomeMapName; char *szAnnounceVersion; /* This is initialised in init_globals */ char *szNetbiosAliases; + char *szDomainSID; int max_log_size; int mangled_stack; int max_xmit; @@ -436,6 +437,7 @@ struct parm_struct {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL}, {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars}, {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL}, + {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL}, {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL}, {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL}, {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set}, @@ -839,6 +841,8 @@ FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName) FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion) FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases) +FN_GLOBAL_STRING(lp_domainsid,&Globals.szDomainSID) + FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy) FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport) FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy) diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 95b69ef4d9..06b785bd87 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -423,13 +423,13 @@ static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len) hdr->reserved = 0; /* reserved */ } -static void make_rpc_reply(char *inbuf, char *q, char *base, int data_len) +static void make_rpc_reply(char *inbuf, char *q, int data_len) { uint32 callid = RIVAL(inbuf, 12); RPC_HDR hdr; create_rpc_reply(&hdr, callid, data_len); - smb_io_rpc_hdr(False, &hdr, q, base, 4); + smb_io_rpc_hdr(False, &hdr, q, q, 4); } static int lsa_reply_open_policy(char *q, char *base) @@ -455,6 +455,18 @@ static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate) hdr->undoc = terminate; } +static void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate) +{ + make_uni_hdr(&(hdr->unihdr), max_len, len, terminate); + hdr->undoc_buffer = len > 0 ? 1 : 0; +} + +static void make_unistr(UNISTR *str, char *buf) +{ + /* store the string (null-terminated copy) */ + PutUniCode((char *)(str->buffer), buf); +} + static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate) { /* set up string lengths. add one if string is not null-terminated */ @@ -469,6 +481,16 @@ static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate) str->buffer[len] = (uint16)terminate; } +static void make_dom_sid2(DOM_SID2 *sid2, char *sid_str) +{ + int len_sid_str = strlen(sid_str); + + sid2->type = 0x5; + sid2->undoc = 0; + make_uni_hdr2(&(sid2->hdr), len_sid_str, len_sid_str, 0); + make_unistr (&(sid2->str), sid_str); +} + static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid) { int domlen = strlen(dom_name); @@ -508,6 +530,79 @@ static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base, return q - start; } +/* pretty much hard-coded choice of "other" sids, unfortunately... */ +static void make_dom_ref(DOM_R_REF *ref, + char *dom_name, char *dom_sid, + char *other_sid1, char *other_sid2, char *other_sid3) +{ + int len_dom_name = strlen(dom_name); + int len_other_sid1 = strlen(other_sid1); + int len_other_sid2 = strlen(other_sid2); + int len_other_sid3 = strlen(other_sid3); + + ref->undoc_buffer = 1; + ref->num_ref_doms_1 = 4; + ref->buffer_dom_name = 1; + ref->max_entries = 32; + ref->num_ref_doms_2 = 4; + + make_uni_hdr2(&(ref->hdr_dom_name ), len_dom_name , len_dom_name , 0); + make_uni_hdr2(&(ref->hdr_ref_dom[0]), len_other_sid1, len_other_sid1, 0); + make_uni_hdr2(&(ref->hdr_ref_dom[1]), len_other_sid2, len_other_sid2, 0); + make_uni_hdr2(&(ref->hdr_ref_dom[2]), len_other_sid3, len_other_sid3, 0); + + if (dom_name != NULL) + { + make_unistr(&(ref->uni_dom_name), dom_name); + } + + make_dom_sid(&(ref->ref_dom[0]), dom_sid ); + make_dom_sid(&(ref->ref_dom[1]), other_sid1); + make_dom_sid(&(ref->ref_dom[2]), other_sid2); + make_dom_sid(&(ref->ref_dom[3]), other_sid3); +} + +static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, + int num_entries, char *dom_sids[MAX_LOOKUP_SIDS], + char *dom_name, char *dom_sid, + char *other_sid1, char *other_sid2, char *other_sid3) +{ + int i; + + make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid, + other_sid1, other_sid2, other_sid3); + + r_l->num_entries = num_entries; + r_l->undoc_buffer = 1; + r_l->num_entries2 = num_entries; + + for (i = 0; i < num_entries; i++) + { + make_dom_sid2(&(r_l->dom_sid[i]), dom_sids[i]); + } + + r_l->num_entries3 = num_entries; +} + +static int lsa_reply_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, char *q, char *base, + char *dom_name, char *dom_sid, + char *other_sid1, char *other_sid2, char *other_sid3) +{ + char *start = q; + LSA_R_LOOKUP_SIDS r_l; + + /* set up the LSA Lookup SIDs response */ + make_reply_lookup_sids(&r_l, 0, NULL, /* q_l->num_entries, q_l->dom_sids, */ + dom_name, dom_sid, other_sid1, other_sid2, other_sid3); + r_l.status = 0x0; + + /* store the response in the SMB stream */ + q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4); + + /* return length of SMB data stored */ + return q - start; +} + static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, char chal[8], int status) { memcpy(r_c->srv_chal.data, chal, sizeof(r_c->srv_chal.data)); @@ -757,3 +852,44 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, /* return length of SMB data stored */ return q - start; } + + +static void api_lsa_open_policy( char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + + /* we might actually want to decode the query, but it's not necessary */ + /* lsa_io_q_open_policy(...); */ + + /* return a 20 byte policy handle */ + reply_len = lsa_reply_open_policy(*rdata + 0x18, *rdata + 0x18); + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; +} + +static void api_lsa_query_info( char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + + LSA_Q_QUERY_INFO q_i; + pstring dom_name; + pstring dom_sid; + + /* grab the info class and policy handle */ + lsa_io_q_query(True, &q_i, data + 0x18, data + 0x18, 4); + + pstrcpy(dom_name, lp_workgroup()); + pstrcpy(dom_sid , lp_domainsid()); + + /* construct reply. return status is always 0x0 */ + reply_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata + 0x18, + dom_name, dom_sid); + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; +} |