summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-03-30 22:25:08 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:19:01 -0500
commit261c004d7bf85de945a1a3956c1d8f15075bc224 (patch)
tree3bacb2553161bece2fe06d3a6c29a0f4b82de97c /source3
parentb0bcb483697249123f92f5ac477c98b579135887 (diff)
downloadsamba-261c004d7bf85de945a1a3956c1d8f15075bc224.tar.gz
samba-261c004d7bf85de945a1a3956c1d8f15075bc224.tar.bz2
samba-261c004d7bf85de945a1a3956c1d8f15075bc224.zip
r22014: Make us pass RANDOMIPC test again :-(. This is an ugly check-in,
but I've no option. Jeremy. (This used to be commit c3a565081d70b209a4f9e6e8f1859bf7194a5f74)
Diffstat (limited to 'source3')
-rw-r--r--source3/lib/util.c23
-rw-r--r--source3/lib/util_str.c36
-rw-r--r--source3/libsmb/clidgram.c5
-rw-r--r--source3/libsmb/cliprint.c12
-rw-r--r--source3/libsmb/clirap.c18
-rw-r--r--source3/libsmb/clirap2.c4
-rw-r--r--source3/nmbd/nmbd_browsesync.c2
-rw-r--r--source3/nmbd/nmbd_elections.c2
-rw-r--r--source3/nmbd/nmbd_incomingdgrams.c18
-rw-r--r--source3/nmbd/nmbd_packets.c6
-rw-r--r--source3/nmbd/nmbd_processlogon.c38
-rw-r--r--source3/nmbd/nmbd_sendannounce.c2
-rw-r--r--source3/smbd/lanman.c878
13 files changed, 714 insertions, 330 deletions
diff --git a/source3/lib/util.c b/source3/lib/util.c
index cf8d49c502..809071662d 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -3124,3 +3124,26 @@ int this_is_smp(void)
return 0;
#endif
}
+
+/****************************************************************
+ Return a safe offset into a buffer, or NULL.
+****************************************************************/
+
+char *get_safe_offset(const char *buf_base, size_t buf_len, char *ptr, size_t off)
+{
+ const char *end_base = buf_base + buf_len;
+ const char *end_ptr = ptr + off;
+
+ if (!buf_base || !ptr) {
+ return NULL;
+ }
+
+ if (end_base < buf_base || end_ptr < ptr) {
+ return NULL; /* wrap. */
+ }
+
+ if (end_ptr < end_base) {
+ return ptr;
+ }
+ return NULL;
+}
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index ccf0af8b62..032627db94 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -424,10 +424,10 @@ void string_replace( pstring s, char oldc, char newc )
}
/**
- Skip past some strings in a buffer.
-**/
+ * Skip past some strings in a buffer - old version - no checks.
+ * **/
-char *skip_string(char *buf,size_t n)
+char *push_skip_string(char *buf,size_t n)
{
while (n--)
buf += strlen(buf) + 1;
@@ -435,6 +435,35 @@ char *skip_string(char *buf,size_t n)
}
/**
+ Skip past some strings in a buffer. Buffer may not be
+ null terminated. end_ptr points to the first byte after
+ then end of the buffer.
+**/
+
+char *skip_string(const char *base, size_t len, char *buf, size_t n)
+{
+ const char *end_ptr = base + len;
+
+ if (end_ptr < base || !base || !buf || buf >= end_ptr) {
+ return NULL;
+ }
+
+ while (n--) {
+ /* Skip the string */
+ while (*buf) {
+ buf++;
+ if (buf >= end_ptr) {
+ return NULL;
+ }
+ }
+ /* Skip the '\0' */
+ buf++;
+ }
+
+ return buf;
+}
+
+/**
Count the number of characters in a string. Normally this will
be the same as the number of bytes in a string for single byte strings,
but will be different for multibyte.
@@ -2591,4 +2620,3 @@ size_t utf16_len_n(const void *src, size_t n)
return len;
}
-
diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c
index a983f485ab..b6a9cfb31a 100644
--- a/source3/libsmb/clidgram.c
+++ b/source3/libsmb/clidgram.c
@@ -85,7 +85,10 @@ BOOL cli_send_mailslot(BOOL unique, const char *mailslot,
SSVAL(ptr,smb_vwv16,2);
p2 = smb_buf(ptr);
fstrcpy(p2,mailslot);
- p2 = skip_string(p2,1);
+ p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2,1);
+ if (!p2) {
+ return False;
+ }
memcpy(p2,buf,len);
p2 += len;
diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c
index 5798e94554..e33a3564eb 100644
--- a/source3/libsmb/cliprint.c
+++ b/source3/libsmb/cliprint.c
@@ -64,16 +64,16 @@ int cli_print_queue(struct cli_state *cli,
SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */
p += 2;
pstrcpy_base(p,"zWrLeh", param); /* parameter description? */
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
pstrcpy_base(p,"WWzWWDDzz", param); /* returned data format */
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
pstrcpy_base(p,cli->share, param); /* name of queue */
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */
SSVAL(p,2,1000); /* size of bytes of returned data buffer */
p += 4;
pstrcpy_base(p,"", param); /* subformat */
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
DEBUG(4,("doing cli_print_queue for %s\n", cli->share));
@@ -133,9 +133,9 @@ int cli_printjob_del(struct cli_state *cli, int job)
SSVAL(p,0,81); /* DosPrintJobDel() */
p += 2;
pstrcpy_base(p,"W", param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
pstrcpy_base(p,"", param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
SSVAL(p,0,job);
p += 2;
diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c
index 4be03e16f0..3fc95e8429 100644
--- a/source3/libsmb/clirap.c
+++ b/source3/libsmb/clirap.c
@@ -86,9 +86,9 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
SSVAL(p,0,132); /* api number */
p += 2;
pstrcpy_base(p,"OOWb54WrLh",param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
pstrcpy_base(p,"WB21BWDWWDDDDDDDzzzD",param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
SSVAL(p,0,1);
p += 2;
pstrcpy_base(p,user,param);
@@ -147,9 +147,9 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co
SSVAL(p,0,0); /* api number */
p += 2;
pstrcpy_base(p,"WrLeh",param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
pstrcpy_base(p,"B13BWz",param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
SSVAL(p,0,1);
/*
* Win2k needs a *smaller* buffer than 0xFFFF here -
@@ -225,11 +225,11 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
SSVAL(p,0,0x68); /* api number */
p += 2;
pstrcpy_base(p,"WrLehDz", param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
pstrcpy_base(p,"B16BBDz", param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
SSVAL(p,0,uLevel);
SSVAL(p,2,CLI_BUFFER_SIZE);
p += 4;
@@ -314,11 +314,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
SSVAL(p,0,214); /* SamOEMChangePassword command. */
p += 2;
pstrcpy_base(p, "zsT", param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
pstrcpy_base(p, "B516B16", param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
pstrcpy_base(p,user, param);
- p = skip_string(p,1);
+ p = skip_string(param,sizeof(param),p,1);
SSVAL(p,0,532);
p += 2;
diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c
index d6a44f4ea2..9ab8997871 100644
--- a/source3/libsmb/clirap2.c
+++ b/source3/libsmb/clirap2.c
@@ -91,7 +91,7 @@
/* put string s at p with max len n and increment p past string */
#define PUTSTRING(p,s,n) do {\
push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\
- p = skip_string(p,1);\
+ p = push_skip_string(p,1);\
} while(0)
/* put string s and p, using fixed len l, and increment p by l */
#define PUTSTRINGF(p,s,l) do {\
@@ -111,7 +111,7 @@
/* get asciiz string s from p, increment p past string */
#define GETSTRING(p,s) do {\
pull_ascii_pstring(s,p);\
- p = skip_string(p,1);\
+ p = push_skip_string(p,1);\
} while(0)
/* get fixed length l string s from p, increment p by l */
#define GETSTRINGF(p,s,l) do {\
diff --git a/source3/nmbd/nmbd_browsesync.c b/source3/nmbd/nmbd_browsesync.c
index 9535a3115a..ddb223de9f 100644
--- a/source3/nmbd/nmbd_browsesync.c
+++ b/source3/nmbd/nmbd_browsesync.c
@@ -125,7 +125,7 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_
/* The call below does CH_UNIX -> CH_DOS conversion. JRA */
push_pstring_base(p, myname, outbuf);
- p = skip_string(p,1);
+ p = skip_string(outbuf,sizeof(outbuf),p,1);
if( DEBUGLVL( 4 ) ) {
dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" );
diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c
index 3aadd70b83..fbdb6c4524 100644
--- a/source3/nmbd/nmbd_elections.c
+++ b/source3/nmbd/nmbd_elections.c
@@ -53,7 +53,7 @@ static void send_election_dgram(struct subnet_record *subrec, const char *workgr
strupper_m(srv_name);
/* The following call does UNIX -> DOS charset conversion. */
pstrcpy_base(p, srv_name, outbuf);
- p = skip_string(p,1);
+ p = skip_string(outbuf,sizeof(outbuf),p,1);
send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
global_myname(), 0,
diff --git a/source3/nmbd/nmbd_incomingdgrams.c b/source3/nmbd/nmbd_incomingdgrams.c
index 880700c72c..616b5df9db 100644
--- a/source3/nmbd/nmbd_incomingdgrams.c
+++ b/source3/nmbd/nmbd_incomingdgrams.c
@@ -416,7 +416,7 @@ done:
Process an incoming LanMan host announcement packet.
*******************************************************************/
-void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
+void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf, int len)
{
struct dgram_packet *dgram = &p->packet.dgram;
uint32 servertype = IVAL(buf,1);
@@ -429,10 +429,16 @@ void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct
unstring work_name;
unstring source_name;
fstring comment;
- char *s = buf+9;
+ char *s = get_safe_offset(buf,len,buf,9);
+ if (!s) {
+ return;
+ }
START_PROFILE(lm_host_announce);
- s = skip_string(s,1);
+ s = skip_string(buf,len,s,1);
+ if (!s) {
+ return;
+ }
pull_ascii(comment, s, sizeof(fstring), 43, STR_TERMINATE);
pull_ascii_nstring(announce_name,sizeof(announce_name),buf+9);
@@ -568,7 +574,7 @@ static void send_backup_list_response(struct subnet_record *subrec,
myname[15]='\0';
push_pstring_base(p, myname, outbuf);
- p = skip_string(p,1);
+ p = skip_string(outbuf,sizeof(outbuf),p,1);
/* Look for backup browsers in this workgroup. */
@@ -604,7 +610,7 @@ static void send_backup_list_response(struct subnet_record *subrec,
DEBUG(5,("send_backup_list_response: Adding server %s number %d\n",
p, count));
- p = skip_string(p,1);
+ p = skip_string(outbuf,sizeof(outbuf),p,1);
}
#endif
@@ -809,7 +815,7 @@ done:
through the "lm announce" parameter in smb.conf)
******************************************************************/
-void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf)
+void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf, int len)
{
struct dgram_packet *dgram = &p->packet.dgram;
unstring workgroup_name;
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index 89362392fe..5ec6be1307 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -1153,10 +1153,10 @@ mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
switch (command) {
case ANN_HostAnnouncement:
debug_browse_data(buf, len);
- process_lm_host_announce(subrec, p, buf+1);
+ process_lm_host_announce(subrec, p, buf+1, len > 1 ? len-1 : 0);
break;
case ANN_AnnouncementRequest:
- process_lm_announce_request(subrec, p, buf+1);
+ process_lm_announce_request(subrec, p, buf+1, len > 1 ? len-1 : 0);
break;
default:
DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
@@ -1899,7 +1899,7 @@ BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
SSVAL(ptr,smb_vwv16,2);
p2 = smb_buf(ptr);
safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
- p2 = skip_string(p2,1);
+ p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2,1);
if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c
index 232f430b66..6b10d61267 100644
--- a/source3/nmbd/nmbd_processlogon.c
+++ b/source3/nmbd/nmbd_processlogon.c
@@ -91,7 +91,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
pstrcpy(my_name, global_myname());
- code = SVAL(buf,0);
+ code = get_safe_offset(buf,len,buf,2) ? SVAL(buf,0) : -1;
DEBUG(4,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code));
switch (code) {
@@ -100,21 +100,21 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
fstring mach_str, user_str, getdc_str;
char *q = buf + 2;
char *machine = q;
- char *user = skip_string(machine,1);
+ char *user = skip_string(buf,len,machine,1);
- if (PTR_DIFF(user, buf) >= len) {
+ if (!user || PTR_DIFF(user, buf) >= len) {
DEBUG(0,("process_logon_packet: bad packet\n"));
return;
}
- getdc = skip_string(user,1);
+ getdc = skip_string(buf,len,user,1);
- if (PTR_DIFF(getdc, buf) >= len) {
+ if (!getdc || PTR_DIFF(getdc, buf) >= len) {
DEBUG(0,("process_logon_packet: bad packet\n"));
return;
}
- q = skip_string(getdc,1);
+ q = skip_string(buf,len,getdc,1);
- if (PTR_DIFF(q + 5, buf) > len) {
+ if (!q || PTR_DIFF(q + 5, buf) > len) {
DEBUG(0,("process_logon_packet: bad packet\n"));
return;
}
@@ -136,7 +136,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
fstrcpy(reply_name, "\\\\");
fstrcat(reply_name, my_name);
push_ascii_fstring(q, reply_name);
- q = skip_string(q, 1); /* PDC name */
+ q = skip_string(outbuf,sizeof(outbuf),q, 1); /* PDC name */
SSVAL(q, 0, token);
q += 2;
@@ -164,15 +164,15 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
return;
}
- getdc = skip_string(machine,1);
+ getdc = skip_string(buf,len,machine,1);
- if (PTR_DIFF(getdc, buf) >= len) {
+ if (!getdc || PTR_DIFF(getdc, buf) >= len) {
DEBUG(0,("process_logon_packet: bad packet\n"));
return;
}
- q = skip_string(getdc,1);
+ q = skip_string(buf,len,getdc,1);
- if (PTR_DIFF(q, buf) >= len) {
+ if (!q || PTR_DIFF(q, buf) >= len) {
DEBUG(0,("process_logon_packet: bad packet\n"));
return;
}
@@ -232,7 +232,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
fstrcpy(reply_name,my_name);
push_ascii_fstring(q, reply_name);
- q = skip_string(q, 1); /* PDC name */
+ q = skip_string(outbuf,sizeof(outbuf),q, 1); /* PDC name */
/* PDC and domain name */
if (!short_request) {
@@ -301,9 +301,9 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
return;
}
- q = skip_string(getdc,1);
+ q = skip_string(buf,len,getdc,1);
- if (PTR_DIFF(q + 8, buf) >= len) {
+ if (!q || PTR_DIFF(q + 8, buf) >= len) {
DEBUG(0,("process_logon_packet: bad packet\n"));
return;
}
@@ -540,16 +540,16 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
/* Domain info */
- q = skip_string(q, 1); /* PDC name */
+ q = skip_string(buf,len,q, 1); /* PDC name */
- if (PTR_DIFF(q, buf) >= len) {
+ if (!q || PTR_DIFF(q, buf) >= len) {
DEBUG(0,("process_logon_packet: bad packet\n"));
return;
}
- q = skip_string(q, 1); /* Domain name */
+ q = skip_string(buf,len,q, 1); /* Domain name */
- if (PTR_DIFF(q, buf) >= len) {
+ if (!q || PTR_DIFF(q, buf) >= len) {
DEBUG(0,("process_logon_packet: bad packet\n"));
return;
}
diff --git a/source3/nmbd/nmbd_sendannounce.c b/source3/nmbd/nmbd_sendannounce.c
index 7fcedc557e..0cd481649d 100644
--- a/source3/nmbd/nmbd_sendannounce.c
+++ b/source3/nmbd/nmbd_sendannounce.c
@@ -566,7 +566,7 @@ for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name ));
myname[15]='\0';
push_pstring_base(p, myname, outbuf);
- p = skip_string(p,1);
+ p = skip_string(outbuf,sizeof(outbuf),p,1);
for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) {
/* The entries are of the form a.b.c.d */
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index e42d96b11e..905b6a023a 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -50,10 +50,13 @@ extern userdom_struct current_user_info;
#define SHPWLEN 8 /* share password length */
-static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param, char *data,
- int mdrcnt, int mprcnt,
- char **rdata, char **rparam,
- int *rdata_len, int *rparam_len);
+static BOOL api_Unsupported(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt, int mprcnt,
+ char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len);
+
static BOOL api_TooSmall(connection_struct *conn, uint16 vuid, char *param, char *data,
int mdrcnt, int mprcnt,
char **rdata, char **rparam,
@@ -585,7 +588,7 @@ static void fill_printq_info_52(connection_struct *conn, int snum,
lp_servicename(snum)));
goto err;
}
-
+
if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername,
"Windows 4.0", 0)) )
{
@@ -597,17 +600,17 @@ static void fill_printq_info_52(connection_struct *conn, int snum,
trim_string(driver.info_3->driverpath, "\\print$\\WIN40\\0\\", 0);
trim_string(driver.info_3->datafile, "\\print$\\WIN40\\0\\", 0);
trim_string(driver.info_3->helpfile, "\\print$\\WIN40\\0\\", 0);
-
+
PACKI(desc, "W", 0x0400); /* don't know */
PACKS(desc, "z", driver.info_3->name); /* long printer name */
PACKS(desc, "z", driver.info_3->driverpath); /* Driverfile Name */
PACKS(desc, "z", driver.info_3->datafile); /* Datafile name */
PACKS(desc, "z", driver.info_3->monitorname); /* language monitor */
-
+
fstrcpy(location, "\\\\%L\\print$\\WIN40\\0");
standard_sub_basic( "", "", location, sizeof(location)-1 );
PACKS(desc,"z", location); /* share to retrieve files */
-
+
PACKS(desc,"z", driver.info_3->defaultdatatype); /* default data type */
PACKS(desc,"z", driver.info_3->helpfile); /* helpfile name */
PACKS(desc,"z", driver.info_3->driverpath); /* driver name */
@@ -627,12 +630,12 @@ static void fill_printq_info_52(connection_struct *conn, int snum,
PACKS(desc,"z",driver.info_3->dependentfiles[i]); /* driver files to copy */
DEBUG(3,("Dependent File: %s:\n",driver.info_3->dependentfiles[i]));
}
-
+
/* sanity check */
if ( i != count )
DEBUG(3,("fill_printq_info_52: file count specified by client [%d] != number of dependent files [%i]\n",
count, i));
-
+
DEBUG(3,("fill_printq_info on <%s> gave %d entries\n", SERVICE(snum),i));
desc->errcode=NERR_Success;
@@ -645,7 +648,7 @@ err:
done:
if ( printer )
free_a_printer( &printer, 2 );
-
+
if ( driver.info_3 )
free_a_printer_driver( driver, 3 );
}
@@ -743,7 +746,7 @@ static int get_printerdrivernumber(int snum)
lp_servicename(snum)));
goto done;
}
-
+
if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername,
"Windows 4.0", 0)) )
{
@@ -751,7 +754,7 @@ static int get_printerdrivernumber(int snum)
printer->info_2->drivername));
goto done;
}
-
+
/* count the number of files */
while ( driver.info_3->dependentfiles && *driver.info_3->dependentfiles[result] )
result++;
@@ -759,39 +762,50 @@ static int get_printerdrivernumber(int snum)
done:
if ( printer )
free_a_printer( &printer, 2 );
-
+
if ( driver.info_3 )
free_a_printer_driver( driver, 3 );
-
+
return result;
}
-static BOOL api_DosPrintQGetInfo(connection_struct *conn,
- uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
char *QueueName = p;
unsigned int uLevel;
int count=0;
int snum;
- char* str3;
+ char *str3;
struct pack_desc desc;
print_queue_struct *queue=NULL;
print_status_struct status;
char* tmpdata=NULL;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
memset((char *)&status,'\0',sizeof(status));
memset((char *)&desc,'\0',sizeof(desc));
-
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
- str3 = p + 4;
-
+
+ p = skip_string(param,tpscnt,p,1);
+ if (!p) {
+ return False;
+ }
+ uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
+ str3 = get_safe_offset(param,tpscnt,p,4) ? p + 4 : 0;
+ /* Check if string exists. */
+ if (skip_string(param,tpscnt,str3,1) == NULL) {
+ return False;
+ }
+
/* remove any trailing username */
if ((p = strchr_m(QueueName,'%')))
*p = 0;
@@ -883,16 +897,18 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
View list of all print jobs on all queues.
****************************************************************************/
-static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param, char* data,
- int mdrcnt, int mprcnt,
- char **rdata, char** rparam,
- int *rdata_len, int *rparam_len)
+static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt, int mprcnt,
+ char **rdata, char** rparam,
+ int *rdata_len, int *rparam_len)
{
- char *param_format = param+2;
- char *output_format1 = skip_string(param_format,1);
- char *p = skip_string(output_format1,1);
- unsigned int uLevel = SVAL(p,0);
- char *output_format2 = p + 4;
+ char *param_format = get_safe_offset(param,tpscnt,param,2);
+ char *output_format1 = skip_string(param,tpscnt,param_format,1);
+ char *p = skip_string(param,tpscnt,output_format1,1);
+ unsigned int uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
+ char *output_format2 = get_safe_offset(param,tpscnt,p,4);
int services = lp_numservices();
int i, n;
struct pack_desc desc;
@@ -901,6 +917,13 @@ static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param,
int *subcntarr = NULL;
int queuecnt = 0, subcnt = 0, succnt = 0;
+ if (!param_format || !output_format1 || !p || !output_format2) {
+ return False;
+ }
+
+ uLevel = SVAL(p,0);
+ output_format2 = p + 4;
+
memset((char *)&desc,'\0',sizeof(desc));
DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
@@ -1252,16 +1275,18 @@ static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
extracted from lists saved by nmbd on the local host.
****************************************************************************/
-static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param, char *data,
- int mdrcnt, int mprcnt, char **rdata,
- char **rparam, int *rdata_len, int *rparam_len)
+static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt, int mprcnt, char **rdata,
+ char **rparam, int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
- uint32 servertype = IVAL(p,4);
+ char *str1 = get_safe_offset(param, tpscnt, param, 2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
+ int uLevel = get_safe_offset(param, tpscnt, p, 2) ? SVAL(p,0) : -1;
+ int buf_len = get_safe_offset(param,tpscnt, p, 4) ? SVAL(p,2) : 0;
+ uint32 servertype = get_safe_offset(param,tpscnt,p,8) ? IVAL(p,4) : 0;
char *p2;
int data_len, fixed_len, string_len;
int f_len = 0, s_len = 0;
@@ -1272,6 +1297,10 @@ static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param
BOOL domain_request;
BOOL local_request;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
/* If someone sets all the bits they don't really mean to set
DOMAIN_ENUM and LOCAL_LIST_ONLY, they just want all the
known servers. */
@@ -1307,6 +1336,9 @@ static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param
DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
if (strcmp(str1, "WrLehDz") == 0) {
+ if (skip_string(param,tpscnt,p,1) == NULL) {
+ return False;
+ }
pull_ascii_fstring(domain, p);
} else {
fstrcpy(domain, lp_workgroup());
@@ -1399,18 +1431,24 @@ static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param
command 0x34 - suspected of being a "Lookup Names" stub api
****************************************************************************/
-static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid, char *param, char *data,
- int mdrcnt, int mprcnt, char **rdata,
- char **rparam, int *rdata_len, int *rparam_len)
+static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt, int mprcnt, char **rdata,
+ char **rparam, int *rdata_len, int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
+ int uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
+ int buf_len = get_safe_offset(param,tpscnt,p,4) ? SVAL(p,2) : 0;
int counted=0;
int missed=0;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
DEBUG(5,("RNetGroupGetUsers: %s %s %s %d %d\n",
str1, str2, p, uLevel, buf_len));
@@ -1582,18 +1620,25 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
return len;
}
-static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *netname = skip_string(str2,1);
- char *p = skip_string(netname,1);
- int uLevel = SVAL(p,0);
- int snum = find_service(netname);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *netname = skip_string(param,tpscnt,str2,1);
+ char *p = skip_string(param,tpscnt,netname,1);
+ int uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
+ int snum;
+ if (!str1 || !str2 || !netname || !p) {
+ return False;
+ }
+
+ snum = find_service(netname);
if (snum < 0) {
return False;
}
@@ -1638,22 +1683,21 @@ static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *para
Share names longer than 12 bytes must be skipped.
****************************************************************************/
-static BOOL api_RNetShareEnum( connection_struct *conn,
- uint16 vuid,
- char *param,
- char *data,
- int mdrcnt,
- int mprcnt,
- char **rdata,
- char **rparam,
- int *rdata_len,
- int *rparam_len )
+static BOOL api_RNetShareEnum( connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,
+ int mprcnt,
+ char **rdata,
+ char **rparam,
+ int *rdata_len,
+ int *rparam_len )
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
+ int uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
+ int buf_len = get_safe_offset(param,tpscnt,p,4) ? SVAL(p,2) : 0;
char *p2;
int count = 0;
int total=0,counted=0;
@@ -1662,6 +1706,10 @@ static BOOL api_RNetShareEnum( connection_struct *conn,
int data_len, fixed_len, string_len;
int f_len = 0, s_len = 0;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
if (!prefix_ok(str1,"WrLeh")) {
return False;
}
@@ -1743,15 +1791,17 @@ static BOOL api_RNetShareEnum( connection_struct *conn,
Add a share
****************************************************************************/
-static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
+ int uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
fstring sharename;
fstring comment;
pstring pathname;
@@ -1760,6 +1810,10 @@ static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,ch
int snum;
int res = ERRunsup;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
/* check it's a supported varient */
if (!prefix_ok(str1,RAP_WShareAdd_REQ)) {
return False;
@@ -1771,6 +1825,10 @@ static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,ch
return False;
}
+ /* Do we have a string ? */
+ if (skip_string(data,mdrcnt,data,1) == NULL) {
+ return False;
+ }
pull_ascii_fstring(sharename,data);
snum = find_service(sharename);
if (snum >= 0) { /* already exists */
@@ -1778,6 +1836,10 @@ static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,ch
goto error_exit;
}
+ if (mdrcnt < 28) {
+ return False;
+ }
+
/* only support disk share adds */
if (SVAL(data,14)!=STYPE_DISKTREE) {
return False;
@@ -1789,6 +1851,10 @@ static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,ch
goto error_exit;
}
+ /* Do we have a string ? */
+ if (skip_string(data,mdrcnt,data+offset,1) == NULL) {
+ return False;
+ }
pull_ascii_fstring(comment, offset? (data+offset) : "");
offset = IVAL(data, 26);
@@ -1798,6 +1864,10 @@ static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,ch
goto error_exit;
}
+ /* Do we have a string ? */
+ if (skip_string(data,mdrcnt,data+offset,1) == NULL) {
+ return False;
+ }
pull_ascii_pstring(pathname, offset? (data+offset) : "");
string_replace(sharename, '"', ' ');
@@ -1858,23 +1928,29 @@ static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,ch
view list of groups available
****************************************************************************/
-static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
int i;
int errflags=0;
int resume_context, cli_buf_size;
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
struct pdb_search *search;
struct samr_displayentry *entries;
int num_entries;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
if (strcmp(str1,"WrLeh") != 0) {
return False;
}
@@ -1901,8 +1977,8 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
return False;
}
- resume_context = SVAL(p,0);
- cli_buf_size=SVAL(p+2,0);
+ resume_context = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
+ cli_buf_size= get_safe_offset(param,tpscnt,p,4) ? SVAL(p+2,0) : 0;
DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: "
"%d\n", resume_context, cli_buf_size));
@@ -1958,16 +2034,18 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
Get groups that a user is a member of.
******************************************************************/
-static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *UserName = skip_string(str2,1);
- char *p = skip_string(UserName,1);
- int uLevel = SVAL(p,0);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *UserName = skip_string(param,tpscnt,str2,1);
+ char *p = skip_string(param,tpscnt,UserName,1);
+ int uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
const char *level_string;
int count=0;
struct samu *sampw = NULL;
@@ -1981,6 +2059,10 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
enum lsa_SidType type;
TALLOC_CTX *mem_ctx;
+ if (!str1 || !str2 || !UserName || !p) {
+ return False;
+ }
+
*rparam_len = 8;
*rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
if (!*rparam) {
@@ -2091,10 +2173,12 @@ done:
Get all users.
******************************************************************/
-static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_RNetUserEnum(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
int count_sent=0;
int num_users=0;
@@ -2103,9 +2187,13 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
struct pdb_search *search;
struct samr_displayentry *users;
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
+
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
if (strcmp(str1,"WrLeh") != 0)
return False;
@@ -2117,8 +2205,8 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
* h -> return parameter total number of users
*/
- resume_context = SVAL(p,0);
- cli_buf_size=SVAL(p+2,0);
+ resume_context = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
+ cli_buf_size= get_safe_offset(param,tpscnt,p,4) ? SVAL(p+2,0) : 0;
DEBUG(10,("api_RNetUserEnum:resume context: %d, client buffer size: %d\n",
resume_context, cli_buf_size));
@@ -2189,10 +2277,12 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
Get the time of day info.
****************************************************************************/
-static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
struct tm *t;
time_t unixdate = time(NULL);
@@ -2245,21 +2335,38 @@ static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,ch
Set the user password.
*****************************************************************************/
-static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param,char *data,
+static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- char *p = skip_string(param+2,2);
+ char *np = get_safe_offset(param,tpscnt,param,2);
+ char *p = skip_string(param,tpscnt,np,2);
fstring user;
fstring pass1,pass2;
+ if (!np || !p) {
+ return False;
+ }
+
+ /* Do we have a string ? */
+ if (skip_string(param,tpscnt,p,1) == NULL) {
+ return False;
+ }
pull_ascii_fstring(user,p);
- p = skip_string(p,1);
+ p = skip_string(param,tpscnt,p,1);
+ if (!p) {
+ return False;
+ }
memset(pass1,'\0',sizeof(pass1));
memset(pass2,'\0',sizeof(pass2));
+ if (get_safe_offset(param,tpscnt,p,32) == NULL) {
+ return False;
+ }
memcpy(pass1,p,16);
memcpy(pass2,p+16,16);
@@ -2331,19 +2438,24 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
Set the user password (SamOEM version - gets plaintext).
****************************************************************************/
-static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *param,char *data,
+static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
fstring user;
- char *p = param + 2;
+ char *p = get_safe_offset(param,tpscnt,param,2);
*rparam_len = 2;
*rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
if (!*rparam) {
return False;
}
+ if (!p) {
+ return False;
+ }
*rdata_len = 0;
SSVAL(*rparam,0,NERR_badpass);
@@ -2352,17 +2464,35 @@ static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *
* Check the parameter definition is correct.
*/
- if(!strequal(param + 2, "zsT")) {
- DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
+ /* Do we have a string ? */
+ if (skip_string(param,tpscnt,p,1) == 0) {
+ return False;
+ }
+ if(!strequal(p, "zsT")) {
+ DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", p));
+ return False;
+ }
+ p = skip_string(param, tpscnt, p, 1);
+ if (!p) {
return False;
}
- p = skip_string(p, 1);
+ /* Do we have a string ? */
+ if (skip_string(param,tpscnt,p,1) == 0) {
+ return False;
+ }
if(!strequal(p, "B516B16")) {
DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
return False;
}
- p = skip_string(p,1);
+ p = skip_string(param,tpscnt,p,1);
+ if (!p) {
+ return False;
+ }
+ /* Do we have a string ? */
+ if (skip_string(param,tpscnt,p,1) == 0) {
+ return False;
+ }
p += pull_ascii_fstring(user,p);
DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
@@ -2386,21 +2516,29 @@ static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *
Form: <W> <>
****************************************************************************/
-static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param,char *data,
+static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- int function = SVAL(param,0);
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ int function = get_safe_offset(param,tpscnt,param,2) ? SVAL(param,0) : 0;
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
uint32 jobid;
int snum;
fstring sharename;
int errcode;
WERROR werr = WERR_OK;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+ if (get_safe_offset(param,tpscnt,p,2) == NULL) {
+ return False;
+ }
if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
return False;
@@ -2457,19 +2595,25 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
Purge a print queue - or pause or resume it.
****************************************************************************/
-static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- int function = SVAL(param,0);
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *QueueName = skip_string(str2,1);
+ int function = get_safe_offset(param,tpscnt,param,2) ? SVAL(param,0) : 0;
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *QueueName = skip_string(param,tpscnt,str2,1);
int errcode = NERR_notsupported;
int snum;
WERROR werr = WERR_OK;
+ if (!str1 || !str2 || !QueueName) {
+ return False;
+ }
+
/* check it's a supported varient */
if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
return(False);
@@ -2533,21 +2677,29 @@ static int check_printjob_info(struct pack_desc* desc,
return True;
}
-static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_PrintJobInfo(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
struct pack_desc desc;
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
uint32 jobid;
fstring sharename;
- int uLevel = SVAL(p,2);
- int function = SVAL(p,4);
+ int uLevel = get_safe_offset(param,tpscnt,p,4) ? SVAL(p,2) : -1;
+ int function = get_safe_offset(param,tpscnt,p,6) ? SVAL(p,4) : -1;
int place, errcode;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+ if (get_safe_offset(param,tpscnt,p,2) == NULL) {
+ return False;
+ }
if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
return False;
*rparam_len = 4;
@@ -2609,18 +2761,24 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
Get info about the server.
****************************************************************************/
-static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
+ int uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
char *p2;
int struct_len;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
DEBUG(4,("NetServerGetInfo level %d\n",uLevel));
/* check it's a supported varient */
@@ -2715,7 +2873,10 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
current_user_info.domain,
comment, sizeof(comment));
StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
}
}
@@ -2741,16 +2902,22 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
Get info about the server.
****************************************************************************/
-static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
+static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
char *p2;
- int level = SVAL(p,0);
+ int level = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
+
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
DEBUG(4,("NetWkstaGetInfo level %d\n",level));
@@ -2775,23 +2942,35 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
SSVAL(*rparam,2,0); /* converter word */
p = *rdata;
- p2 = p + 22;
+ p2 = get_safe_offset(*rdata,*rdata_len,p,22);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* host name */
pstrcpy(p2,get_local_machine_name());
strupper_m(p2);
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
p += 4;
SIVAL(p,0,PTR_DIFF(p2,*rdata));
pstrcpy(p2,current_user_info.smb_name);
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
p += 4;
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
pstrcpy(p2,lp_workgroup());
strupper_m(p2);
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
p += 4;
SCVAL(p,0,lp_major_announce_version()); /* system version - e.g 4 in 4.1 */
@@ -2800,12 +2979,18 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
SIVAL(p,0,PTR_DIFF(p2,*rdata));
pstrcpy(p2,lp_workgroup()); /* don't know. login domain?? */
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
p += 4;
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* don't know */
pstrcpy(p2,"");
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
p += 4;
*rdata_len = PTR_DIFF(p2,*rdata);
@@ -2985,16 +3170,18 @@ There is no auxiliary data in the response.
#define AF_OP_ACCOUNTS 3
-static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
+static BOOL api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *UserName = skip_string(str2,1);
- char *p = skip_string(UserName,1);
- int uLevel = SVAL(p,0);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *UserName = skip_string(param,tpscnt,str2,1);
+ char *p = skip_string(param,tpscnt,UserName,1);
+ int uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
char *p2;
const char *level_string;
@@ -3007,6 +3194,10 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
vuser->user.unix_name));
}
+ if (!str1 || !str2 || !UserName || !p) {
+ return False;
+ }
+
*rparam_len = 6;
*rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
if (!*rparam) {
@@ -3042,7 +3233,10 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SSVAL(*rparam,2,0); /* converter word */
p = *rdata;
- p2 = p + usri11_end;
+ p2 = get_safe_offset(*rdata,*rdata_len,p,usri11_end);
+ if (!p2) {
+ return False;
+ }
memset(p,0,21);
fstrcpy(p+usri11_name,UserName); /* 21 bytes - user name */
@@ -3055,16 +3249,25 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
if (uLevel >= 10) {
SIVAL(p,usri11_comment,PTR_DIFF(p2,p)); /* comment */
pstrcpy(p2,"Comment");
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,usri11_usr_comment,PTR_DIFF(p2,p)); /* user_comment */
pstrcpy(p2,"UserComment");
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
/* EEK! the cifsrap.txt doesn't have this in!!!! */
SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */
pstrcpy(p2,((vuser != NULL) ? vuser->user.full_name : UserName));
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
}
if (uLevel == 11) {
@@ -3074,22 +3277,34 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SIVALS(p,usri11_password_age,-1); /* password age */
SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
pstrcpy(p2, vuser && vuser->homedir ? vuser->homedir : "");
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
pstrcpy(p2,"");
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,usri11_last_logon,0); /* last logon */
SIVAL(p,usri11_last_logoff,0); /* last logoff */
SSVALS(p,usri11_bad_pw_count,-1); /* bad pw counts */
SSVALS(p,usri11_num_logons,-1); /* num logons */
SIVAL(p,usri11_logon_server,PTR_DIFF(p2,p)); /* logon server */
pstrcpy(p2,"\\\\*");
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
SSVAL(p,usri11_country_code,0); /* country code */
SIVAL(p,usri11_workstations,PTR_DIFF(p2,p)); /* workstations */
pstrcpy(p2,"");
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
SIVALS(p,usri11_max_storage,-1); /* max storage */
SSVAL(p,usri11_units_per_week,168); /* units per week */
@@ -3098,7 +3313,10 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
/* a simple way to get logon hours at all times. */
memset(p2,0xff,21);
SCVAL(p2,21,0); /* fix zero termination */
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
SSVAL(p,usri11_code_page,0); /* code page */
}
@@ -3110,22 +3328,34 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
pstrcpy(p2, vuser && vuser->homedir ? vuser->homedir : "");
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
*p2++ = 0;
SSVAL(p,52,0); /* flags */
SIVAL(p,54,PTR_DIFF(p2,*rdata)); /* script_path */
pstrcpy(p2,vuser && vuser->logon_script ? vuser->logon_script : "");
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
if (uLevel == 2) {
SIVAL(p,60,0); /* auth_flags */
SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
pstrcpy(p2,((vuser != NULL) ? vuser->user.full_name : UserName));
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,68,0); /* urs_comment */
SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
pstrcpy(p2,"");
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,76,0); /* workstations */
SIVAL(p,80,0); /* last_logon */
SIVAL(p,84,0); /* last_logoff */
@@ -3144,7 +3374,10 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
standard_sub_basic("", "", tmp, sizeof(tmp));
pstrcpy(p2, tmp);
}
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2,1);
+ if (!p2) {
+ return False;
+ }
SSVAL(p,110,49); /* country_code */
SSVAL(p,112,860); /* code page */
}
@@ -3157,14 +3390,16 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
return(True);
}
-static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param,char *data,
+static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
int uLevel;
struct pack_desc desc;
char* name;
@@ -3172,12 +3407,19 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
Don't depend on vuser being non-null !!. JRA */
user_struct *vuser = get_valid_user_struct(vuid);
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
if(vuser != NULL) {
DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid,
vuser->user.unix_name));
}
- uLevel = SVAL(p,0);
+ uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
+ if (skip_string(param,tpscnt,p+2,1) == NULL) {
+ return False;
+ }
name = p + 2;
memset((char *)&desc,'\0',sizeof(desc));
@@ -3251,15 +3493,21 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
api_WAccessGetUserPerms
****************************************************************************/
-static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *user = skip_string(str2,1);
- char *resource = skip_string(user,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *user = skip_string(param,tpscnt,str2,1);
+ char *resource = skip_string(param,tpscnt,user,1);
+
+ if (!str1 || !str2 || !user || !resource) {
+ return False;
+ }
DEBUG(3,("WAccessGetUserPerms user=%s resource=%s\n",user,resource));
@@ -3287,14 +3535,16 @@ static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid, char *p
api_WPrintJobEnumerate
****************************************************************************/
-static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintJobGetInfo(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
int uLevel;
int count;
int i;
@@ -3306,7 +3556,11 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
print_status_struct status;
char *tmpdata=NULL;
- uLevel = SVAL(p,2);
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
+ uLevel = get_safe_offset(param,tpscnt,p,4) ? SVAL(p,2) : -1;
memset((char *)&desc,'\0',sizeof(desc));
memset((char *)&status,'\0',sizeof(status));
@@ -3380,15 +3634,17 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
return True;
}
-static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char* name = p;
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
+ char *name = p;
int uLevel;
int count;
int i, succnt=0;
@@ -3397,11 +3653,18 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
print_queue_struct *queue=NULL;
print_status_struct status;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
memset((char *)&desc,'\0',sizeof(desc));
memset((char *)&status,'\0',sizeof(status));
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
+ p = skip_string(param,tpscnt,p,1);
+ if (!p) {
+ return False;
+ }
+ uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
@@ -3524,24 +3787,33 @@ static void fill_printdest_info(connection_struct *conn, int snum, int uLevel,
}
}
-static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintDestGetInfo(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
char* PrinterName = p;
int uLevel;
struct pack_desc desc;
int snum;
char *tmpdata=NULL;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
memset((char *)&desc,'\0',sizeof(desc));
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
+ p = skip_string(param,tpscnt,p,1);
+ if (!p) {
+ return False;
+ }
+ uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel,PrinterName));
@@ -3595,23 +3867,29 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
return True;
}
-static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintDestEnum(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
int uLevel;
int queuecnt;
int i, n, succnt=0;
struct pack_desc desc;
int services = lp_numservices();
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
memset((char *)&desc,'\0',sizeof(desc));
- uLevel = SVAL(p,0);
+ uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel));
@@ -3670,21 +3948,27 @@ static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,
return True;
}
-static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintDriverEnum(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
int uLevel;
int succnt;
struct pack_desc desc;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
memset((char *)&desc,'\0',sizeof(desc));
- uLevel = SVAL(p,0);
+ uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : 0;
DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel));
@@ -3727,21 +4011,26 @@ static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *para
return True;
}
-static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
+static BOOL api_WPrintQProcEnum(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
int uLevel;
int succnt;
struct pack_desc desc;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
memset((char *)&desc,'\0',sizeof(desc));
- uLevel = SVAL(p,0);
+ uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel));
@@ -3785,21 +4074,27 @@ static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param
return True;
}
-static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+static BOOL api_WPrintPortEnum(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
int uLevel;
int succnt;
struct pack_desc desc;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
memset((char *)&desc,'\0',sizeof(desc));
- uLevel = SVAL(p,0);
+ uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel));
@@ -3844,27 +4139,33 @@ static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,
return True;
}
-
/****************************************************************************
List open sessions
****************************************************************************/
-static BOOL api_RNetSessionEnum(connection_struct *conn,uint16 vuid, char *param, char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+
+static BOOL api_RNetSessionEnum(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
+ char *str1 = get_safe_offset(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1,1);
+ char *p = skip_string(param,tpscnt,str2,1);
int uLevel;
struct pack_desc desc;
struct sessionid *session_list;
int i, num_sessions;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
memset((char *)&desc,'\0',sizeof(desc));
- uLevel = SVAL(p,0);
+ uLevel = get_safe_offset(param,tpscnt,p,2) ? SVAL(p,0) : -1;
DEBUG(3,("RNetSessionEnum uLevel=%d\n",uLevel));
DEBUG(7,("RNetSessionEnum req string=%s\n",str1));
@@ -3951,10 +4252,12 @@ static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param, char
The request is not supported.
****************************************************************************/
-static BOOL api_Unsupported(connection_struct *conn, uint16 vuid, char *param, char *data,
- int mdrcnt, int mprcnt,
- char **rdata, char **rparam,
- int *rdata_len, int *rparam_len)
+static BOOL api_Unsupported(connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt, int mprcnt,
+ char **rdata, char **rparam,
+ int *rdata_len, int *rparam_len)
{
*rparam_len = 4;
*rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
@@ -3975,7 +4278,9 @@ static BOOL api_Unsupported(connection_struct *conn, uint16 vuid, char *param, c
static const struct {
const char *name;
int id;
- BOOL (*fn)(connection_struct *,uint16,char *,char *,
+ BOOL (*fn)(connection_struct *, uint16,
+ char *, int,
+ char *, int,
int,int,char **,char **,int *,int *);
BOOL auth_user; /* Deny anonymous access? */
} api_commands[] = {
@@ -4030,6 +4335,8 @@ int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *
int api_command;
char *rdata = NULL;
char *rparam = NULL;
+ const char *name1 = NULL;
+ const char *name2 = NULL;
int rdata_len = 0;
int rparam_len = 0;
BOOL reply=False;
@@ -4040,12 +4347,25 @@ int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *
return 0;
}
+ if (tpscnt < 2) {
+ return 0;
+ }
api_command = SVAL(params,0);
+ /* Is there a string at position params+2 ? */
+ if (skip_string(params,tpscnt,params+2,1)) {
+ name1 = params + 2;
+ } else {
+ name1 = "";
+ }
+ name2 = skip_string(params,tpscnt,params+2,1);
+ if (!name2) {
+ name2 = "";
+ }
DEBUG(3,("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
api_command,
- params+2,
- skip_string(params+2,1),
+ name1,
+ name2,
tdscnt,tpscnt,mdrcnt,mprcnt));
for (i=0;api_commands[i].name;i++) {
@@ -4082,7 +4402,11 @@ int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *
return -1;
}
- reply = api_commands[i].fn(conn,vuid,params,data,mdrcnt,mprcnt,
+ reply = api_commands[i].fn(conn,
+ vuid,
+ params,tpscnt, /* params + length */
+ data,tdscnt, /* data + length */
+ mdrcnt,mprcnt,
&rdata,&rparam,&rdata_len,&rparam_len);
@@ -4093,7 +4417,7 @@ int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *
/* if we get False back then it's actually unsupported */
if (!reply) {
- reply = api_Unsupported(conn,vuid,params,data,mdrcnt,mprcnt,
+ reply = api_Unsupported(conn,vuid,params,tpscnt,data,tdscnt,mdrcnt,mprcnt,
&rdata,&rparam,&rdata_len,&rparam_len);
}