From 72a86f514f0c92b69499718e63f5dd73ebece56e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 9 Oct 1997 14:40:46 +0000 Subject: credentials.c: use UTIME structure (defined and commented in smb.h to be time, secs, since 01jan1970) pipes.c: another sub-function. util.c: added char *unistr2(uint16 *buff) function. same as unistr except it takes uint16* instead of char*. smbparse.c smb.h: more structure sorting. proto.h: the usual. --- source/include/proto.h | 3 + source/include/smb.h | 6 +- source/lib/util.c | 28 ++++++- source/libsmb/credentials.c | 8 +- source/smbd/pipes.c | 190 +++++++++++++++++++++++++++++++++++++++++++- source/smbparse.c | 2 +- 6 files changed, 224 insertions(+), 13 deletions(-) diff --git a/source/include/proto.h b/source/include/proto.h index fab69de3d1a..b0589ede190 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -628,6 +628,7 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, int *rdata_len,int *rparam_len); +char *dom_sid_to_string(DOM_SID *sid); /*The following definitions come from predict.c */ @@ -653,6 +654,7 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); +BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); /*The following definitions come from replace.c */ @@ -1040,6 +1042,7 @@ BOOL is_myname(char *s); void set_remote_arch(enum remote_arch_types type); enum remote_arch_types get_remote_arch(); char *skip_unicode_string(char *buf,int n); +char *unistr2(uint16 *buf); char *unistr(char *buf); int unistrncpy(char *dst, char *src, int len); int unistrcpy(char *dst, char *src); diff --git a/source/include/smb.h b/source/include/smb.h index 9f5279fca00..7d7677b3fc8 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -565,11 +565,7 @@ typedef struct lsa_r_lookup_sids typedef struct dom_name_info { uint32 uni_str_len; -#if 1 /* don't know if buffer is null-terminated */ - UNISTR buffer; -#else /* or length indicated by uni_str_len member */ - uint16 buffer[MAX_UNISTRLEN]; -#endif + UNISTR str; } DOM_NAME; diff --git a/source/lib/util.c b/source/lib/util.c index 39d3c61b9e3..701f3245541 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -4216,7 +4216,27 @@ char *skip_unicode_string(char *buf,int n) /******************************************************************* Return a ascii version of a unicode string -Hack alert: uses fixed buffer and only handles ascii strings +Hack alert: uses fixed buffer(s) and only handles ascii strings +********************************************************************/ +#define MAXUNI 1024 +char *unistr2(uint16 *buf) +{ + static char lbufs[8][MAXUNI]; + static int nexti; + char *lbuf = lbufs[nexti]; + char *p; + nexti = (nexti+1)%8; + for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++) + { + *p = *buf; + } + *p = 0; + return lbuf; +} + +/******************************************************************* +Return a ascii version of a unicode string +Hack alert: uses fixed buffer(s) and only handles ascii strings ********************************************************************/ #define MAXUNI 1024 char *unistr(char *buf) @@ -4225,9 +4245,13 @@ char *unistr(char *buf) static int nexti; char *lbuf = lbufs[nexti]; char *p; + nexti = (nexti+1)%8; - for (p = lbuf; *buf && p -lbuf < MAXUNI-2; p++, buf += 2) + + for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2) + { *p = *buf; + } *p = 0; return lbuf; } diff --git a/source/libsmb/credentials.c b/source/libsmb/credentials.c index efa0d83ec28..4c81177fb20 100644 --- a/source/libsmb/credentials.c +++ b/source/libsmb/credentials.c @@ -59,7 +59,7 @@ Input: Output: 8 byte credential ****************************************************************************/ -void cred_create(char *session_key, char *stored_cred, uint32 time, +void cred_create(char *session_key, char *stored_cred, UTIME timestamp, char *cred) { char key2[7]; @@ -67,7 +67,7 @@ void cred_create(char *session_key, char *stored_cred, uint32 time, char timecred[8]; memcpy(timecred, stored_cred, 8); - SIVAL(timecred, 0, IVAL(stored_cred, 0) + time); + SIVAL(timecred, 0, IVAL(stored_cred, 0) + timestamp.time); E1(session_key, timecred, buf); memset(key2, 0, 7); @@ -90,11 +90,11 @@ Output: returns 0 otherwise ****************************************************************************/ int cred_assert(char *cred, char *session_key, char *stored_cred, - uint32 time) + NTTIME timestamp) { char cred2[8]; - cred_create(session_key, stored_cred, time, cred2); + cred_create(session_key, stored_cred, timestamp, cred2); return memcmp(cred, cred2, 8) == 0; } diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c index bedf847cc43..13cdff262d7 100644 --- a/source/smbd/pipes.c +++ b/source/smbd/pipes.c @@ -370,6 +370,20 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data, fragment length. I've decided to do it based on operation number :-) */ +/* RID username mapping function. just for fun, it maps to the unix uid */ +static uint32 name_to_rid(char *user_name) +{ + struct passwd *pw = Get_Pwnam(user_name, False); + if (!pw) + { + DEBUG(1,("Username %s is invalid on this system\n", user_name)); + return (uint32)(-1); + } + + return (uint32)(pw->pw_uid); +} + + /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ char *dom_sid_to_string(DOM_SID *sid) { @@ -504,6 +518,14 @@ static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate) str->buffer[len] = (uint16)terminate; } +static void make_dom_rid2(DOM_RID2 *rid2, uint32 rid) +{ + rid2->type = 0x5; + rid2->undoc = 0x5; + rid2->rid = rid; + rid2->rid_idx = 0; +} + static void make_dom_sid2(DOM_SID2 *sid2, char *sid_str) { int len_sid_str = strlen(sid_str); @@ -585,6 +607,28 @@ static void make_dom_ref(DOM_R_REF *ref, make_dom_sid(&(ref->ref_dom[3]), other_sid3); } +static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l, + int num_entries, uint32 dom_rids[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_rid2(&(r_l->dom_rid[i]), dom_rids[i]); + } + + r_l->num_entries3 = num_entries; +} + static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS], char *dom_name, char *dom_sid, @@ -627,6 +671,26 @@ static int lsa_reply_lookup_sids(char *q, char *base, return q - start; } +static int lsa_reply_lookup_rids(char *q, char *base, + int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS], + char *dom_name, char *dom_sid, + char *other_sid1, char *other_sid2, char *other_sid3) +{ + char *start = q; + LSA_R_LOOKUP_RIDS r_l; + + /* set up the LSA Lookup RIDs response */ + make_reply_lookup_rids(&r_l, num_entries, dom_rids, + 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_rids(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)); @@ -952,6 +1016,129 @@ static void api_lsa_lookup_sids( char *param, char *data, *rdata_len = reply_len + 0x18; } +static void api_lsa_lookup_names( char *param, char *data, + char **rdata, int *rdata_len ) +{ + int reply_len; + + int i; + LSA_Q_LOOKUP_RIDS q_l; + pstring dom_name; + pstring dom_sid; + uint32 dom_rids[MAX_LOOKUP_SIDS]; + + /* grab the info class and policy handle */ + lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data + 0x18, 4); + + pstrcpy(dom_name, lp_workgroup()); + pstrcpy(dom_sid , lp_domainsid()); + + /* convert received RIDs to strings, so we can do them. */ + for (i = 0; i < q_l.num_entries; i++) + { + char *user_name = unistr2(q_l.lookup_name[i].str.buffer); + dom_rids[i] = name_to_rid(user_name); + } + + /* construct reply. return status is always 0x0 */ + reply_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata + 0x18, + q_l.num_entries, dom_rids, /* text-converted SIDs */ + dom_name, dom_sid, /* domain name, domain SID */ + "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */ + + /* construct header, now that we know the reply length */ + make_rpc_reply(data, *rdata, reply_len); + *rdata_len = reply_len + 0x18; +} + +#if 0 + q = data + 0x18; + policyhandle = q; q += 20; + nentries = qIVAL; + DEBUG(4,("lookupnames entries %d\n",nentries)); + q += 4; /* skip second count */ + q += 8 * nentries; /* skip pointers */ + for (nnames = 0; nnames < nentries; nnames++) + { + names[nnames] = q; /* set name string to unicode header */ + q += IVAL(q,0)*2; /* guessing here */ + } + /* There's a translated sids structure next but it looks fals */ + + DEBUG(4,("lookupnames line %d\n",__LINE__)); + /* formulate reply */ + q = *rdata + 0x18; + qSIVAL(2); /* bufptr */ + qSIVAL(4); /* number of referenced domains + - need one per each identifier authority in call */ + qSIVAL(2); /* dom bufptr */ + qSIVAL(32); /* max entries */ + qSIVAL(4); /* number of reference domains? */ + + qunihdr(lp_workgroup()); /* reference domain */ + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-1"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-5"); + qSIVAL(2); /* sid bufptr */ + + qunihdr("S-1-3"); + qSIVAL(2); /* sid bufptr */ + + qunistr(lp_workgroup()); + DEBUG(4,("lookupnames line %d\n",__LINE__)); + + strcpy(domsid,lp_domainsid()); + p = strtok(domsid+2,"-"); + revision = atoi(p); + identauth = atoi(strtok(0,"-")); + numsubauths = 0; + while (p = strtok(0, "-")) + subauths[numsubauths++] = atoi(p); + qSIVAL(numsubauths); + qSCVAL(revision); + qSCVAL(numsubauths); + qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */ + qRSIVAL(identauth); /* next 4 bytes */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + for (i = 0; i < numsubauths; i++) + { +qSIVAL(subauths[i]); + } + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-1"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */ + DEBUG(4,("lookupsid line %d\n",__LINE__)); + + qunistr("S-1-5"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */ + + qunistr("S-1-3"); + qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */ + + qSIVAL(nentries); + qSIVAL(2); /* bufptr */ + qSIVAL(nentries); + DEBUG(4,("lookupnames line %d\n",__LINE__)); + for (i = 0; i < nentries; i++) + { +qSSVAL(5); /* SID name use 5 == well known sid, 1 == user sid see showacls */ +qSSVAL(5); /* undocumented */ + DEBUG(4,("lookupnames line %d\n",__LINE__)); +qSIVAL(name_to_rid(names[i])); + DEBUG(4,("lookupnames name_to_rid %d\n",name_to_rid(names[i]))); +qSIVAL(0); /* domain index out of above reference domains */ + } + qSIVAL(nentries); /* mapped count */ + endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); + break; + +#endif + + /* space in front of this function so that make proto doesn't pick it up */ void _dummy_function(void) { @@ -971,5 +1158,6 @@ static void api_lsa_lookup_sids( char *param, char *data, lsa_reply_sam_logoff(NULL,NULL,NULL,NULL,t,0); api_lsa_open_policy(NULL,NULL,NULL,NULL); api_lsa_query_info(NULL,NULL,NULL,NULL); - api_lsa_lookup_sids(NULL,NULL,NULL,NULL); + api_lsa_lookup_sids (NULL,NULL,NULL,NULL); + api_lsa_lookup_names(NULL,NULL,NULL,NULL); } diff --git a/source/smbparse.c b/source/smbparse.c index 0d93c2e8ad5..01438281ef1 100644 --- a/source/smbparse.c +++ b/source/smbparse.c @@ -513,7 +513,7 @@ char* smb_io_dom_name(BOOL io, DOM_NAME *name, char *q, char *base, int align) /* don't know if len is specified by uni_str_len member... */ /* assume unicode string is unicode-null-terminated, instead */ - q = smb_io_unistr(io, &(name->buffer), q, base, align); + q = smb_io_unistr(io, &(name->str), q, base, align); return q; } -- cgit