diff options
Diffstat (limited to 'source/smbd/ipc.c')
-rw-r--r-- | source/smbd/ipc.c | 262 |
1 files changed, 167 insertions, 95 deletions
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 8852e57e8b6..415c939bf38 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -24,8 +24,6 @@ */ #include "includes.h" -#include "loadparm.h" -#include "pcap.h" #ifdef CHECK_TYPES #undef CHECK_TYPES @@ -467,7 +465,7 @@ static void fill_printjob_info(int cnum, int snum, int uLevel, time_t t = queue->time; /* the client expects localtime */ - t += GMT_TO_LOCAL*TimeDiff(t); + t -= TimeDiff(t); PACKI(desc,"W",((snum%0xFF)<<8) | (queue->job%0xFF)); /* uJobId */ if (uLevel == 1) { @@ -479,7 +477,7 @@ static void fill_printjob_info(int cnum, int snum, int uLevel, PACKI(desc,"W",n+1); /* uPosition */ PACKI(desc,"W",queue->status); /* fsStatus */ PACKS(desc,"z",""); /* pszStatus */ - PACKI(desc,"D",queue->time); /* ulSubmitted */ + PACKI(desc,"D",t); /* ulSubmitted */ PACKI(desc,"D",queue->size); /* ulSize */ PACKS(desc,"z",queue->file); /* pszComment */ } @@ -488,7 +486,7 @@ static void fill_printjob_info(int cnum, int snum, int uLevel, PACKS(desc,"z",queue->user); /* pszUserName */ PACKI(desc,"W",n+1); /* uPosition */ PACKI(desc,"W",queue->status); /* fsStatus */ - PACKI(desc,"D",queue->time); /* ulSubmitted */ + PACKI(desc,"D",t); /* ulSubmitted */ PACKI(desc,"D",queue->size); /* ulSize */ PACKS(desc,"z","Samba"); /* pszComment */ PACKS(desc,"z",queue->file); /* pszDocument */ @@ -751,44 +749,65 @@ struct srv_info_struct filter out unwanted server info ******************************************************************/ static BOOL filter_server_info(struct srv_info_struct *server, - char *domain) + BOOL domains, + char *domain, uint32 request) { - if (*domain) - return(strequal(domain, server->domain)); - - return (True); /* be indiscriminate: get all servers! */ -} - -/******************************************************************* - find server in the files saved by nmbd. Return True if we find it. - ******************************************************************/ -static BOOL find_server(struct srv_info_struct *servers, int num_servers, - char *domain, char *name) -{ - int count; - - if (!servers || num_servers == 0) return (False); - - for (count = 0; count < num_servers; count++) { - struct srv_info_struct *s; - - s = &servers[count]; - - if (strequal(name, s->name)) { - StrnCpy(domain, s->domain, sizeof(pstring)-1); - return (True); + if (*domain == 0) + { + if (strequal(lp_workgroup(), server->domain)) { + return True; + } + else if (domains) + { + DEBUG(4,("primary domain:reject %8x %s %s\n",request,server->name,server->domain)); + return False; + } + else if ((request & SV_TYPE_DOMAIN_ENUM) && + (server->type & SV_TYPE_DOMAIN_ENUM)) + { + DEBUG(4,("rej:DOM %8x: %s %s\n",server->type,server->name,server->domain)); + return False; + } + + return True; + } + else + { + if (strequal(domain, server->domain)) + { + /* + if (request == SV_TYPE_LOCAL_LIST_ONLY && + !(server->type & SV_TYPE_LOCAL_LIST_ONLY)) + { + DEBUG(4,("rej:LOC %8x: ok %s %s\n",request,server->name,server->domain)); + return False; + } + */ + if ((request == (SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM)) && + !(server->type&SV_TYPE_DOMAIN_ENUM)) + { + DEBUG(4,("rej:LOCDOM %8x: ok %s %s\n",request,server->name,server->domain)); + return False; + } + + return True; + } + else if (!domains) + { + DEBUG(4,("domain:%s %s %s\n",domain,server->name,server->domain)); + return False; + } + return True; } - } - return (False); } - /******************************************************************* get server info lists from the files saved by nmbd. Return the number of entries ******************************************************************/ static int get_server_info(uint32 servertype, - struct srv_info_struct **servers) + struct srv_info_struct **servers, BOOL domains, + char *domain) { FILE *f; pstring fname; @@ -807,18 +826,23 @@ static int get_server_info(uint32 servertype, DEBUG(4,("Can't open %s - %s\n",fname,strerror(errno))); return(0); } + + /* request for everything is code for request all servers */ if (servertype == SV_TYPE_ALL) servertype &= ~SV_TYPE_DOMAIN_ENUM; + DEBUG(4,("Servertype search: %8x domains:%s\n",servertype,BOOLSTR(domains))); + while (!feof(f)) { fstring stype; struct srv_info_struct *s; char *ptr = line; + BOOL ok = True; *ptr = 0; fgets(line,sizeof(line)-1,f); if (!*line) continue; - + if (count == alloced) { alloced += 10; (*servers) = (struct srv_info_struct *) @@ -827,36 +851,63 @@ static int get_server_info(uint32 servertype, bzero((char *)((*servers)+count),sizeof(**servers)*(alloced-count)); } s = &(*servers)[count]; - - s->server_added = True; - + if (!next_token(&ptr,s->name , NULL)) continue; if (!next_token(&ptr,stype , NULL)) continue; if (!next_token(&ptr,s->comment, NULL)) continue; if (!next_token(&ptr,s->domain , NULL)) { - /* this allows us to cop with an old nmbd */ + /* this allows us to cope with an old nmbd */ strcpy(s->domain,my_workgroup()); } - - if (sscanf(stype,"%X",&s->type) != 1) continue; - + + if (sscanf(stype,"%X",&s->type) != 1) { + DEBUG(4,("r:host file ")); + ok = False; + } + /* doesn't match up: don't want it */ - if (!(servertype & s->type)) continue; - - /* server entry is a domain, we haven't asked for domains: don't want it */ - if ((s->type&SV_TYPE_DOMAIN_ENUM) && !(servertype&SV_TYPE_DOMAIN_ENUM)) - continue; - - DEBUG(4,("Server %20s %8x %25s %15s\n", - s->name, stype, s->comment, s->domain)); - - count++; + if (!(servertype & s->type)) { + DEBUG(4,("r:serv type ")); + ok = False; + } + + if ((servertype == ~SV_TYPE_DOMAIN_ENUM) && + (s->type & SV_TYPE_DOMAIN_ENUM)) + { + DEBUG(4,("s:all x dom ")); + ok = False; + } + + if (domains && !(domain && *domain && strequal(domain, s->domain))) + { + if (!(s->type & SV_TYPE_DOMAIN_ENUM)) + { + DEBUG(4,("r:dom enum ")); + ok = False; + } + } + + if (ok) + { + DEBUG(4,("**SV** %20s %8x %25s %15s\n", + s->name, s->type, s->comment, s->domain)); + + s->type |= SV_TYPE_LOCAL_LIST_ONLY; + s->server_added = True; + count++; + } + else + { + DEBUG(4,("%20s %8x %25s %15s\n", + s->name, s->type, s->comment, s->domain)); + } } - + fclose(f); return(count); } + /******************************************************************* fill in a server info structure ******************************************************************/ @@ -936,6 +987,11 @@ static int fill_srv_info(struct srv_info_struct *service, } +static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2) +{ + return(strcmp(s1->name,s2->name)); +} + /**************************************************************************** view list of servers available (or possibly domains). The info is extracted from lists saved by nmbd on the local host @@ -957,8 +1013,14 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data, int counted=0,total=0; int i; fstring domain; - BOOL domain_request = (servertype & SV_TYPE_DOMAIN_ENUM) && - !(servertype == SV_TYPE_ALL); + BOOL domains; + BOOL domain_request; + BOOL local_request = servertype & SV_TYPE_LOCAL_LIST_ONLY; + + /*if (servertype == SV_TYPE_ALL) servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);*/ + if (servertype == SV_TYPE_ALL) servertype &= ~SV_TYPE_DOMAIN_ENUM; + + domain_request = servertype & SV_TYPE_DOMAIN_ENUM; domain[0] = 0; p += 8; @@ -966,49 +1028,53 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data, if (!prefix_ok(str1,"WrLehD")) return False; if (!check_server_info(uLevel,str2)) return False; - DEBUG(4, ("server request level: %s\n", str2)); + DEBUG(4, ("server request level: %s %8x ", str2, servertype)); + DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request))); + DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request))); if (strcmp(str1, "WrLehDO") == 0) { - /* asking for servers. we will have to work out which workgroup was - requested, as we maintain lists for multiple workgroups */ + domains = False; } else if (strcmp(str1, "WrLehDz") == 0) { - /* asking for a specific workgroup */ + domains = True; StrnCpy(domain, p, sizeof(fstring)-1); } if (lp_browse_list()) { - total = get_server_info(servertype,&servers); - } - - if (!domain[0] && !domain_request) { - extern fstring remote_machine; - /* must be a server request with an assumed domain. find a domain */ - - if (find_server(servers, total, domain, remote_machine)) { - DEBUG(4, ("No domain specified: using %s for %s\n", - domain, remote_machine)); - } else { - /* default to soemthing sensible */ - strcpy(domain,my_workgroup()); - } + total = get_server_info(servertype,&servers,domains,domain); } data_len = fixed_len = string_len = 0; - for (i=0;i<total;i++) - if (filter_server_info(&servers[i],domain)) { - data_len += fill_srv_info(&servers[i],uLevel,0,&f_len,0,&s_len,0); - if (data_len <= buf_len) + qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp); + + { + char *lastname=NULL; + + for (i=0;i<total;i++) + { + struct srv_info_struct *s = &servers[i]; + if (filter_server_info(s,domains,domain, + local_request|domain_request)) { - counted++; - fixed_len += f_len; - string_len += s_len; + if (lastname && strequal(lastname,s->name)) continue; + lastname = s->name; + data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0); + DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n", + s->name, s->type, s->comment, s->domain)); + + if (data_len <= buf_len) + { + counted++; + fixed_len += f_len; + string_len += s_len; + } } } + } *rdata_len = fixed_len + string_len; *rdata = REALLOC(*rdata,*rdata_len); @@ -1020,13 +1086,21 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data, s_len = string_len; { + char *lastname=NULL; int count2 = counted; - for (i = 0; i < total && count2;i++) { - if (filter_server_info(&servers[i],domain)) { - fill_srv_info(&servers[i],uLevel,&p,&f_len,&p2,&s_len,*rdata); - count2--; + for (i = 0; i < total && count2;i++) + { + struct srv_info_struct *s = &servers[i]; + if (filter_server_info(s,domains,domain,local_request|domain_request)) + { + if (lastname && strequal(lastname,s->name)) continue; + lastname = s->name; + fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata); + DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n", + s->name, s->type, s->comment, s->domain)); + count2--; + } } - } } *rparam_len = 8; @@ -1289,7 +1363,7 @@ static BOOL api_NetRemoteTOD(int cnum,int uid, char *param,char *data, /* the client expects to get localtime, not GMT, in this bit (I think, this needs testing) */ - t = LocalTime(&unixdate,GMT_TO_LOCAL); + t = LocalTime(&unixdate); SIVAL(p,4,0); /* msecs ? */ CVAL(p,8) = t->tm_hour; @@ -1551,8 +1625,7 @@ static BOOL api_PrintJobInfo(int cnum,int uid,char *param,char *data, int l = 0; while (l<64 && *s) { - if (isalnum(*s) || strchr("-._",*s)) - name[l++] = *s; + if (issafe(*s)) name[l++] = *s; s++; } name[l] = 0; @@ -1658,7 +1731,7 @@ static BOOL api_RNetServerGetInfo(int cnum,int uid, char *param,char *data, strcpy(comment,lp_serverstring()); - if ((count=get_server_info(SV_TYPE_ALL,&servers))>0) { + if ((count=get_server_info(SV_TYPE_ALL,&servers,False,NULL))>0) { for (i=0;i<count;i++) if (strequal(servers[i].name,local_machine)) { servertype = servers[i].type; @@ -2717,12 +2790,9 @@ int reply_trans(char *inbuf,char *outbuf) while (pscnt < tpscnt || dscnt < tdscnt) { int pcnt,poff,dcnt,doff,pdisp,ddisp; - - receive_smb(Client,inbuf, 0); - show_msg(inbuf); - - /* Ensure this is still a trans packet (sanity check) */ - if(CVAL(inbuf, smb_com) != SMBtrans) + + if (!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT*1000) || + CVAL(inbuf, smb_com) != SMBtrans) { DEBUG(2,("Invalid secondary trans2 packet\n")); if (params) free(params); @@ -2730,6 +2800,8 @@ int reply_trans(char *inbuf,char *outbuf) if (setup) free(setup); return(ERROR(ERRSRV,ERRerror)); } + + show_msg(inbuf); tpscnt = SVAL(inbuf,smb_vwv0); tdscnt = SVAL(inbuf,smb_vwv1); |