Unix SMB/CIFS implementation.
Inter-process communication and named pipe handling
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2007.
SMB Version handling
Copyright (C) John H Terpstra 1995-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
This file handles the named pipe and mailslot calls
#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_TooSmall(connection_struct *conn, uint16 vuid, char *param, char *data,
+/* Limit size of ipc replies */
+
+static char *smb_realloc_limit(void *ptr, size_t size)
+{
+ char *val;
+
+ size = MAX((size),4*1024);
+ val = (char *)SMB_REALLOC(ptr,size);
+ if (val) {
+ memset(val,'\0',size);
+ }
+ return val;
+}
+
+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,
int *rdata_len, int *rparam_len);
-static int CopyExpanded(connection_struct *conn,
- int snum, char **dst, char *src, int *n)
+static int CopyExpanded(connection_struct *conn,
+ int snum, char **dst, char *src, int *p_space_remaining)
{
- pstring buf;
+ TALLOC_CTX *ctx = talloc_tos();
+ char *buf = NULL;
int l;
- if (!src || !dst || !n || !(*dst)) {
+ if (!src || !dst || !p_space_remaining || !(*dst) ||
+ *p_space_remaining <= 0) {
return 0;
}
- StrnCpy(buf,src,sizeof(buf)/2);
- pstring_sub(buf,"%S",lp_servicename(snum));
- standard_sub_conn(conn,buf,sizeof(buf));
- l = push_ascii(*dst,buf,*n, STR_TERMINATE);
+ buf = talloc_strdup(ctx, src);
+ if (!buf) {
+ *p_space_remaining = 0;
+ return 0;
+ }
+ buf = talloc_string_sub(ctx, buf,"%S",lp_servicename(snum));
+ if (!buf) {
+ *p_space_remaining = 0;
+ return 0;
+ }
+ buf = talloc_sub_advanced(ctx,
+ lp_servicename(SNUM(conn)),
+ conn->user,
+ conn->connectpath,
+ conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ buf);
+ if (!buf) {
+ *p_space_remaining = 0;
+ return 0;
+ }
+ l = push_ascii(*dst,buf,*p_space_remaining, STR_TERMINATE);
+ if (l == -1) {
+ return 0;
+ }
(*dst) += l;
- (*n) -= l;
+ (*p_space_remaining) -= l;
return l;
}
return 0;
}
l = push_ascii(*dst,src,*n, STR_TERMINATE);
+ if (l == -1) {
+ return 0;
+ }
(*dst) += l;
(*n) -= l;
return l;
static int StrlenExpanded(connection_struct *conn, int snum, char *s)
{
- pstring buf;
+ TALLOC_CTX *ctx = talloc_tos();
+ char *buf = NULL;
if (!s) {
return 0;
}
- StrnCpy(buf,s,sizeof(buf)/2);
- pstring_sub(buf,"%S",lp_servicename(snum));
- standard_sub_conn(conn,buf,sizeof(buf));
+ buf = talloc_strdup(ctx,s);
+ if (!buf) {
+ return 0;
+ }
+ buf = talloc_string_sub(ctx,buf,"%S",lp_servicename(snum));
+ if (!buf) {
+ return 0;
+ }
+ buf = talloc_sub_advanced(ctx,
+ lp_servicename(SNUM(conn)),
+ conn->user,
+ conn->connectpath,
+ conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ buf);
+ if (!buf) {
+ return 0;
+ }
return strlen(buf) + 1;
}
static char *Expand(connection_struct *conn, int snum, char *s)
{
- static pstring buf;
+ TALLOC_CTX *ctx = talloc_tos();
+ char *buf = NULL;
+
if (!s) {
return NULL;
}
- StrnCpy(buf,s,sizeof(buf)/2);
- pstring_sub(buf,"%S",lp_servicename(snum));
- standard_sub_conn(conn,buf,sizeof(buf));
- return &buf[0];
+ buf = talloc_strdup(ctx,s);
+ if (!buf) {
+ return 0;
+ }
+ buf = talloc_string_sub(ctx,buf,"%S",lp_servicename(snum));
+ if (!buf) {
+ return 0;
+ }
+ return talloc_sub_advanced(ctx,
+ lp_servicename(SNUM(conn)),
+ conn->user,
+ conn->connectpath,
+ conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ buf);
}
/*******************************************************************
Check a API string for validity when we only need to check the prefix.
******************************************************************/
-static BOOL prefix_ok(const char *str, const char *prefix)
+static bool prefix_ok(const char *str, const char *prefix)
{
return(strncmp(str,prefix,strlen(prefix)) == 0);
}
return n;
}
-static BOOL init_package(struct pack_desc *p, int count, int subcount)
+static bool init_package(struct pack_desc *p, int count, int subcount)
{
int n = p->buflen;
int i;
SIVAL(drivdata,0,sizeof drivdata); /* cb */
SIVAL(drivdata,4,1000); /* lVersion */
memset(drivdata+8,0,32); /* szDeviceName */
- push_ascii(drivdata+8,"NULL",-1, STR_TERMINATE);
+ push_ascii(drivdata+8,"NULL",32, STR_TERMINATE);
PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
}
desc->subformat = "z";
break;
default:
+ DEBUG(0,("check_printq_info: invalid level %d\n",
+ uLevel ));
return False;
}
- if (strcmp(desc->format,id1) != 0) {
+ if (id1 == NULL || strcmp(desc->format,id1) != 0) {
+ DEBUG(0,("check_printq_info: invalid format %s\n",
+ id1 ? id1 : "<NULL>" ));
return False;
}
- if (desc->subformat && strcmp(desc->subformat,id2) != 0) {
+ if (desc->subformat && (id2 == NULL || strcmp(desc->subformat,id2) != 0)) {
+ DEBUG(0,("check_printq_info: invalid subformat %s\n",
+ id2 ? id2 : "<NULL>" ));
return False;
}
return True;
Returns True if from tdb, False otherwise.
********************************************************************/
-static BOOL get_driver_name(int snum, pstring drivername)
+static bool get_driver_name(int snum, char **pp_drivername)
{
NT_PRINTER_INFO_LEVEL *info = NULL;
- BOOL in_tdb = False;
+ bool in_tdb = false;
get_a_printer (NULL, &info, 2, lp_servicename(snum));
if (info != NULL) {
- pstrcpy( drivername, info->info_2->drivername);
- in_tdb = True;
+ *pp_drivername = talloc_strdup(talloc_tos(),
+ info->info_2->drivername);
+ in_tdb = true;
free_a_printer(&info, 2);
+ if (!*pp_drivername) {
+ return false;
+ }
}
return in_tdb;
lp_servicename(snum)));
goto err;
}
-
+
if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername,
"Windows 4.0", 0)) )
{
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 );
+ 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 */
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;
done:
if ( printer )
free_a_printer( &printer, 2 );
-
+
if ( driver.info_3 )
free_a_printer_driver( driver, 3 );
}
}
if (uLevel == 3 || uLevel == 4) {
- pstring drivername;
+ char *drivername = NULL;
PACKI(desc,"W",5); /* uPriority */
PACKI(desc,"W",0); /* uStarttime */
PACKS(desc,"z","WinPrint"); /* pszPrProc */
PACKS(desc,"z",NULL); /* pszParms */
PACKS(desc,"z",NULL); /* pszComment - don't ask.... JRA */
- /* "don't ask" that it's done this way to fix corrupted
+ /* "don't ask" that it's done this way to fix corrupted
Win9X/ME printer comments. */
if (!status) {
PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
}
PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */
PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
- get_driver_name(snum,drivername);
+ get_driver_name(snum,&drivername);
+ if (!drivername) {
+ return;
+ }
PACKS(desc,"z",drivername); /* pszDriverName */
PackDriverData(desc); /* pDriverData */
}
lp_servicename(snum)));
goto done;
}
-
+
if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername,
"Windows 4.0", 0)) )
{
printer->info_2->drivername));
goto done;
}
-
+
/* count the number of files */
while ( driver.info_3->dependentfiles && *driver.info_3->dependentfiles[result] )
result++;
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
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);
+ if (!p) {
+ return False;
+ }
+ uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
+ str3 = get_safe_str_ptr(param,tpscnt,p,4);
+ /* str3 may be null here and is checked in check_printq_info(). */
+
/* remove any trailing username */
if ((p = strchr_m(QueueName,'%')))
*p = 0;
*/
*rdata_len = 0;
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,ERRunknownlevel);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,0);
}
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ SAFE_FREE(queue);
+ return False;
+ }
desc.base = *rdata;
desc.buflen = mdrcnt;
} else {
*rdata_len = desc.usedlen;
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ SAFE_FREE(queue);
+ SAFE_FREE(tmpdata);
+ return False;
+ }
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,desc.neededlen);
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_str_ptr(param,tpscnt,param,2);
+ char *output_format1 = skip_string(param,tpscnt,param_format);
+ char *p = skip_string(param,tpscnt,output_format1);
+ unsigned int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
+ char *output_format2 = get_safe_str_ptr(param,tpscnt,p,4);
int services = lp_numservices();
int i, n;
struct pack_desc desc;
int *subcntarr = NULL;
int queuecnt = 0, subcnt = 0, succnt = 0;
+ if (!param_format || !output_format1 || !p) {
+ return False;
+ }
+
memset((char *)&desc,'\0',sizeof(desc));
DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
*/
*rdata_len = 0;
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,ERRunknownlevel);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,0);
}
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
if (!*rdata) {
goto err;
}
*rdata_len = desc.usedlen;
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
goto err;
}
Get info level for a server list query.
****************************************************************************/
-static BOOL check_server_info(int uLevel, char* id)
+static bool check_server_info(int uLevel, char* id)
{
switch( uLevel ) {
case 0:
uint32 type;
fstring comment;
fstring domain;
- BOOL server_added;
+ bool server_added;
};
/*******************************************************************
int count=0;
int alloced=0;
char **lines;
- BOOL local_list_only;
+ bool local_list_only;
int i;
lines = file_lines_load(lock_path(SERVER_LIST), NULL, 0);
fstring stype;
struct srv_info_struct *s;
const char *ptr = lines[i];
- BOOL ok = True;
+ bool ok = True;
+ TALLOC_CTX *frame = NULL;
+ char *p;
if (!*ptr) {
continue;
}
-
+
if (count == alloced) {
- struct srv_info_struct *ts;
-
alloced += 10;
- ts = SMB_REALLOC_ARRAY(*servers,struct srv_info_struct, alloced);
- if (!ts) {
+ *servers = SMB_REALLOC_ARRAY(*servers,struct srv_info_struct, alloced);
+ if (!*servers) {
DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
+ file_lines_free(lines);
return 0;
- } else {
- *servers = ts;
}
memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count));
}
s = &(*servers)[count];
-
- if (!next_token(&ptr,s->name, NULL, sizeof(s->name))) {
+
+ frame = talloc_stackframe();
+ s->name[0] = '\0';
+ if (!next_token_talloc(frame,&ptr,&p, NULL)) {
+ TALLOC_FREE(frame);
continue;
}
- if (!next_token(&ptr,stype, NULL, sizeof(stype))) {
+ fstrcpy(s->name, p);
+
+ stype[0] = '\0';
+ if (!next_token_talloc(frame,&ptr, &p, NULL)) {
+ TALLOC_FREE(frame);
continue;
}
- if (!next_token(&ptr,s->comment, NULL, sizeof(s->comment))) {
+ fstrcpy(stype, p);
+
+ s->comment[0] = '\0';
+ if (!next_token_talloc(frame,&ptr, &p, NULL)) {
+ TALLOC_FREE(frame);
continue;
}
- if (!next_token(&ptr,s->domain, NULL, sizeof(s->domain))) {
+ fstrcpy(s->comment, p);
+
+ s->domain[0] = '\0';
+ if (!next_token_talloc(frame,&ptr,&p, NULL)) {
/* this allows us to cope with an old nmbd */
- fstrcpy(s->domain,lp_workgroup());
+ fstrcpy(s->domain,lp_workgroup());
+ } else {
+ fstrcpy(s->domain, p);
}
-
- if (sscanf(stype,"%X",&s->type) != 1) {
- DEBUG(4,("r:host file "));
- ok = False;
+ TALLOC_FREE(frame);
+
+ if (sscanf(stype,"%X",&s->type) != 1) {
+ DEBUG(4,("r:host file "));
+ ok = False;
}
-
+
/* Filter the servers/domains we return based on what was asked for. */
/* Check to see if we are being asked for a local list only. */
}
/* doesn't match up: don't want it */
- if (!(servertype & s->type)) {
- DEBUG(4,("r:serv type "));
- ok = False;
+ 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: dom mismatch "));
break;
}
- if (buflen) {
- *buflen = struct_len;
- }
- if (stringspace) {
- *stringspace = len;
- }
+ *buflen = struct_len;
+ *stringspace = len;
return struct_len + len;
}
}
-static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
+static bool srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
{
return(strcmp(s1->name,s2->name));
}
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_str_ptr(param, tpscnt, param, 2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
+ int uLevel = get_safe_SVAL(param, tpscnt, p, 0, -1);
+ int buf_len = get_safe_SVAL(param,tpscnt, p, 2, 0);
+ uint32 servertype = get_safe_IVAL(param,tpscnt,p,4, 0);
char *p2;
int data_len, fixed_len, string_len;
int f_len = 0, s_len = 0;
int counted=0,total=0;
int i,missed;
fstring domain;
- BOOL domain_request;
- BOOL local_request;
+ 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
}
/* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
- any other bit (they may just set this bit on it's own) they
+ any other bit (they may just set this bit on its own) they
want all the locally seen servers. However this bit can be
set on its own so set the requested servers to be
ALL - DOMAIN_ENUM. */
DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
if (strcmp(str1, "WrLehDz") == 0) {
+ if (skip_string(param,tpscnt,p) == NULL) {
+ return False;
+ }
pull_ascii_fstring(domain, p);
} else {
fstrcpy(domain, lp_workgroup());
}
*rdata_len = fixed_len + string_len;
- *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
- memset(*rdata,'\0',*rdata_len);
+ *rdata = smb_realloc_limit(*rdata,*rdata_len);
+ if (!*rdata) {
+ return False;
+ }
p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */
p = *rdata;
}
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERRmoredata));
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,counted);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
+ int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
+ int buf_len = get_safe_SVAL(param,tpscnt,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));
*rdata_len = 0;
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVAL(*rparam,0,0x08AC); /* informational warning message */
SSVAL(*rparam,2,0);
get info about a share
****************************************************************************/
-static BOOL check_share_info(int uLevel, char* id)
+static bool check_share_info(int uLevel, char* id)
{
switch( uLevel ) {
case 0:
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *netname = skip_string(param,tpscnt,str2);
+ char *p = skip_string(param,tpscnt,netname);
+ int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
+ int snum;
+ if (!str1 || !str2 || !netname || !p) {
+ return False;
+ }
+
+ snum = find_service(netname);
if (snum < 0) {
return False;
}
return False;
}
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
+ }
p = *rdata;
*rdata_len = fill_share_info(conn,snum,uLevel,&p,&mdrcnt,0,0,0);
if (*rdata_len < 0) {
}
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVAL(*rparam,0,NERR_Success);
SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,*rdata_len);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
+ int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
+ int buf_len = get_safe_SVAL(param,tpscnt,p,2,0);
char *p2;
int count = 0;
int total=0,counted=0;
- BOOL missed = False;
+ bool missed = False;
int i;
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;
}
/* Ensure all the usershares are loaded. */
become_root();
+ load_registry_shares();
count = load_usershare_shares();
unbecome_root();
}
*rdata_len = fixed_len + string_len;
- *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
- memset(*rdata,0,*rdata_len);
-
+ *rdata = smb_realloc_limit(*rdata,*rdata_len);
+ if (!*rdata) {
+ return False;
+ }
+
p2 = (*rdata) + fixed_len; /* auxiliary data (strings) will go here */
p = *rdata;
f_len = fixed_len;
}
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVAL(*rparam,0,missed ? ERRmoredata : NERR_Success);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,counted);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
+ int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
fstring sharename;
fstring comment;
- pstring pathname;
+ char *pathname = NULL;
char *command, *cmdname;
unsigned int offset;
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;
return False;
}
+ /* Do we have a string ? */
+ if (skip_string(data,mdrcnt,data) == NULL) {
+ return False;
+ }
pull_ascii_fstring(sharename,data);
snum = find_service(sharename);
if (snum >= 0) { /* already exists */
goto error_exit;
}
+ if (mdrcnt < 28) {
+ return False;
+ }
+
/* only support disk share adds */
if (SVAL(data,14)!=STYPE_DISKTREE) {
return False;
goto error_exit;
}
+ /* Do we have a string ? */
+ if (skip_string(data,mdrcnt,data+offset) == NULL) {
+ return False;
+ }
pull_ascii_fstring(comment, offset? (data+offset) : "");
offset = IVAL(data, 26);
goto error_exit;
}
- pull_ascii_pstring(pathname, offset? (data+offset) : "");
+ /* Do we have a string ? */
+ if (skip_string(data,mdrcnt,data+offset) == NULL) {
+ return False;
+ }
+
+ pull_ascii_talloc(talloc_tos(), &pathname, offset? (data+offset) : "");
+ if (!pathname) {
+ return false;
+ }
string_replace(sharename, '"', ' ');
string_replace(pathname, '"', ' ');
return False;
}
- asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
- lp_add_share_cmd(), dyn_CONFIGFILE, sharename, pathname, comment);
+ if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
+ lp_add_share_cmd(), get_dyn_CONFIGFILE(), sharename,
+ pathname, comment) == -1) {
+ return false;
+ }
- if (command) {
- DEBUG(10,("api_RNetShareAdd: Running [%s]\n", command ));
+ DEBUG(10,("api_RNetShareAdd: Running [%s]\n", command ));
- if ((res = smbrun(command, NULL)) != 0) {
- DEBUG(1,("api_RNetShareAdd: Running [%s] returned (%d)\n", command, res ));
- SAFE_FREE(command);
- res = ERRnoaccess;
- goto error_exit;
- } else {
- SAFE_FREE(command);
- message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
- }
+ if ((res = smbrun(command, NULL)) != 0) {
+ DEBUG(1,("api_RNetShareAdd: Running [%s] returned (%d)\n",
+ command, res ));
+ SAFE_FREE(command);
+ res = ERRnoaccess;
+ goto error_exit;
} else {
- return False;
+ SAFE_FREE(command);
+ message_send_all(smbd_messaging_context(),
+ MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
}
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVAL(*rparam,0,NERR_Success);
SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,*rdata_len);
error_exit:
*rparam_len = 4;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
*rdata_len = 0;
SSVAL(*rparam,0,res);
SSVAL(*rparam,2,0);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
struct pdb_search *search;
struct samr_displayentry *entries;
int num_entries;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
if (strcmp(str1,"WrLeh") != 0) {
return False;
}
return False;
}
- resume_context = SVAL(p,0);
- cli_buf_size=SVAL(p+2,0);
+ resume_context = get_safe_SVAL(param,tpscnt,p,0,-1);
+ cli_buf_size= get_safe_SVAL(param,tpscnt,p,2,0);
DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: "
"%d\n", resume_context, cli_buf_size));
unbecome_root();
*rdata_len = cli_buf_size;
- *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
+ *rdata = smb_realloc_limit(*rdata,*rdata_len);
+ if (!*rdata) {
+ return False;
+ }
p = *rdata;
*rdata_len = PTR_DIFF(p,*rdata);
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
-
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVAL(*rparam, 0, errflags);
SSVAL(*rparam, 2, 0); /* converter word */
SSVAL(*rparam, 4, i); /* is this right?? */
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *UserName = skip_string(param,tpscnt,str2);
+ char *p = skip_string(param,tpscnt,UserName);
+ int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
const char *level_string;
int count=0;
struct samu *sampw = NULL;
- BOOL ret = False;
+ bool ret = False;
DOM_SID *sids;
gid_t *gids;
size_t num_groups;
size_t i;
NTSTATUS result;
DOM_SID user_sid;
- enum SID_NAME_USE type;
+ enum lsa_SidType type;
+ char *endp = NULL;
TALLOC_CTX *mem_ctx;
+ if (!str1 || !str2 || !UserName || !p) {
+ return False;
+ }
+
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
-
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
+
/* check it's a supported varient */
-
+
if ( strcmp(str1,"zWrLeh") != 0 )
return False;
-
+
switch( uLevel ) {
case 0:
level_string = "B21";
return False;
*rdata_len = mdrcnt + 1024;
- *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
+ *rdata = smb_realloc_limit(*rdata,*rdata_len);
+ if (!*rdata) {
+ return False;
+ }
SSVAL(*rparam,0,NERR_Success);
SSVAL(*rparam,2,0); /* converter word */
p = *rdata;
+ endp = *rdata + *rdata_len;
mem_ctx = talloc_new(NULL);
if (mem_ctx == NULL) {
return False;
}
- /* Lookup the user information; This should only be one of
+ if ( !(sampw = samu_new(mem_ctx)) ) {
+ DEBUG(0, ("samu_new() failed!\n"));
+ TALLOC_FREE(mem_ctx);
+ return False;
+ }
+
+ /* Lookup the user information; This should only be one of
our accounts (not remote domains) */
become_root(); /* ROOT BLOCK */
goto done;
}
- if ( !(sampw = samu_new(mem_ctx)) ) {
- DEBUG(0, ("samu_new() failed!\n"));
- goto done;
- }
-
if ( !pdb_getsampwsid(sampw, &user_sid) ) {
DEBUG(10, ("pdb_getsampwsid(%s) failed for user %s\n",
- sid_string_static(&user_sid), UserName));
+ sid_string_dbg(&user_sid), UserName));
goto done;
}
}
for (i=0; i<num_groups; i++) {
-
const char *grp_name;
-
+
if ( lookup_sid(mem_ctx, &sids[i], NULL, &grp_name, NULL) ) {
- pstrcpy(p, grp_name);
- p += 21;
+ strlcpy(p, grp_name, PTR_DIFF(endp,p));
+ p += 21;
count++;
}
}
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;
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
+ char *endp = NULL;
+
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
if (strcmp(str1,"WrLeh") != 0)
return False;
* e -> return parameter number of entries
* h -> return parameter total number of users
*/
-
- resume_context = SVAL(p,0);
- cli_buf_size=SVAL(p+2,0);
+
+ resume_context = get_safe_SVAL(param,tpscnt,p,0,-1);
+ cli_buf_size= get_safe_SVAL(param,tpscnt,p,2,0);
DEBUG(10,("api_RNetUserEnum:resume context: %d, client buffer size: %d\n",
resume_context, cli_buf_size));
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
/* check it's a supported varient */
if (strcmp("B21",str2) != 0)
return False;
*rdata_len = cli_buf_size;
- *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
+ *rdata = smb_realloc_limit(*rdata,*rdata_len);
+ if (!*rdata) {
+ return False;
+ }
p = *rdata;
+ endp = *rdata + *rdata_len;
become_root();
search = pdb_search_users(ACB_NORMAL);
for (i=0; i<num_users; i++) {
const char *name = users[i].account_name;
-
+
if(((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21)) {
- pstrcpy(p,name);
+ strlcpy(p,name,PTR_DIFF(endp,p));
DEBUG(10,("api_RNetUserEnum:adding entry %d username "
"%s\n",count_sent,p));
- p += 21;
- count_sent++;
+ p += 21;
+ count_sent++;
} else {
/* set overflow error */
DEBUG(10,("api_RNetUserEnum:overflow on entry %d "
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);
char *p;
*rparam_len = 4;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
*rdata_len = 21;
- *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
+ *rdata = smb_realloc_limit(*rdata,*rdata_len);
+ if (!*rdata) {
+ return False;
+ }
SSVAL(*rparam,0,NERR_Success);
SSVAL(*rparam,2,0); /* converter word */
/* the client expects to get localtime, not GMT, in this bit
(I think, this needs testing) */
t = localtime(&unixdate);
+ if (!t) {
+ return False;
+ }
SIVAL(p,4,0); /* msecs ? */
SCVAL(p,8,t->tm_hour);
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_str_ptr(param,tpscnt,param,2);
+ char *p = NULL;
fstring user;
fstring pass1,pass2;
- pull_ascii_fstring(user,p);
-
- p = skip_string(p,1);
+ /* Skip 2 strings. */
+ p = skip_string(param,tpscnt,np);
+ p = skip_string(param,tpscnt,p);
- memset(pass1,'\0',sizeof(pass1));
- memset(pass2,'\0',sizeof(pass2));
- memcpy(pass1,p,16);
- memcpy(pass2,p+16,16);
+ if (!np || !p) {
+ return False;
+ }
+
+ /* Do we have a string ? */
+ if (skip_string(param,tpscnt,p) == NULL) {
+ return False;
+ }
+ pull_ascii_fstring(user,p);
+
+ p = skip_string(param,tpscnt,p);
+ if (!p) {
+ return False;
+ }
+
+ memset(pass1,'\0',sizeof(pass1));
+ memset(pass2,'\0',sizeof(pass2));
+ /*
+ * We use 31 here not 32 as we're checking
+ * the last byte we want to access is safe.
+ */
+ if (!is_offset_safe(param,tpscnt,p,31)) {
+ return False;
+ }
+ memcpy(pass1,p,16);
+ memcpy(pass2,p+16,16);
*rparam_len = 4;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
*rdata_len = 0;
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_str_ptr(param,tpscnt,param,2);
*rparam_len = 2;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
+ if (!p) {
+ return False;
+ }
*rdata_len = 0;
SSVAL(*rparam,0,NERR_badpass);
* 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) == 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);
+ if (!p) {
return False;
}
- p = skip_string(p, 1);
+ /* Do we have a string ? */
+ if (skip_string(param,tpscnt,p) == 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);
+ if (!p) {
+ return False;
+ }
+ /* Do we have a string ? */
+ if (skip_string(param,tpscnt,p) == 0) {
+ return False;
+ }
p += pull_ascii_fstring(user,p);
DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
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_SVAL(param,tpscnt,param,0,0);
+ char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
uint32 jobid;
int snum;
fstring sharename;
int errcode;
WERROR werr = WERR_OK;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+ /*
+ * We use 1 here not 2 as we're checking
+ * the last byte we want to access is safe.
+ */
+ if (!is_offset_safe(param,tpscnt,p,1)) {
+ return False;
+ }
if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
return False;
return(False);
*rparam_len = 4;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
*rdata_len = 0;
if (!print_job_exists(sharename, jobid)) {
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_SVAL(param,tpscnt,param,0,0);
+ char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *QueueName = skip_string(param,tpscnt,str2);
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);
*rparam_len = 4;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
*rdata_len = 0;
+ if (skip_string(param,tpscnt,QueueName) == NULL) {
+ return False;
+ }
snum = print_queue_snum(QueueName);
if (snum == -1) {
case 2: desc->format = "WWzWWDDzz"; break;
case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
case 4: desc->format = "WWzWWDDzzzzzDDDDDDD"; break;
- default: return False;
+ default:
+ DEBUG(0,("check_printjob_info: invalid level %d\n",
+ uLevel ));
+ return False;
+ }
+ if (id == NULL || strcmp(desc->format,id) != 0) {
+ DEBUG(0,("check_printjob_info: invalid format %s\n",
+ id ? id : "<NULL>" ));
+ return False;
}
- if (strcmp(desc->format,id) != 0) return False;
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
uint32 jobid;
- int snum;
fstring sharename;
- int uLevel = SVAL(p,2);
- int function = SVAL(p,4);
+ int uLevel = get_safe_SVAL(param,tpscnt,p,2,-1);
+ int function = get_safe_SVAL(param,tpscnt,p,4,-1);
int place, errcode;
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+ /*
+ * We use 1 here not 2 as we're checking
+ * the last byte we want to access is safe.
+ */
+ if (!is_offset_safe(param,tpscnt,p,1)) {
+ return False;
+ }
if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
return False;
*rparam_len = 4;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
- if ( (snum = lp_servicenumber(sharename)) == -1 ) {
- DEBUG(0,("api_PrintJobInfo: unable to get service number from sharename [%s]\n",
- sharename));
+ if (!share_defined(sharename)) {
+ DEBUG(0,("api_PrintJobInfo: sharen [%s] not defined\n",
+ sharename));
return False;
}
/* change job place in the queue,
data gives the new place */
place = SVAL(data,0);
- if (print_job_set_place(snum, jobid, place)) {
+ if (print_job_set_place(sharename, jobid, place)) {
errcode=NERR_Success;
}
break;
case 0xb:
/* change print job name, data gives the name */
- if (print_job_set_name(snum, jobid, data)) {
+ if (print_job_set_name(sharename, jobid, data)) {
errcode=NERR_Success;
}
break;
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
+ int uLevel = get_safe_SVAL(param,tpscnt,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 */
}
*rdata_len = mdrcnt;
- *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
+ *rdata = smb_realloc_limit(*rdata,*rdata_len);
+ if (!*rdata) {
+ return False;
+ }
p = *rdata;
p2 = p + struct_len;
if (uLevel != 20) {
- srvstr_push(NULL, p,get_local_machine_name(),16,
+ srvstr_push(NULL, 0, p,global_myname(),16,
STR_ASCII|STR_UPPER|STR_TERMINATE);
}
p += 16;
if (uLevel > 0) {
struct srv_info_struct *servers=NULL;
int i,count;
- pstring comment;
+ char *comment = NULL;
+ TALLOC_CTX *ctx = talloc_tos();
uint32 servertype= lp_default_server_announce();
- push_ascii(comment,lp_serverstring(), MAX_SERVER_STRING_LENGTH,STR_TERMINATE);
+ comment = talloc_strdup(ctx,lp_serverstring());
+ if (!comment) {
+ return false;
+ }
if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
for (i=0;i<count;i++) {
- if (strequal(servers[i].name,get_local_machine_name())) {
+ if (strequal(servers[i].name,global_myname())) {
servertype = servers[i].type;
- push_ascii(comment,servers[i].comment,sizeof(pstring),STR_TERMINATE);
+ TALLOC_FREE(comment);
+ comment = talloc_strdup(ctx,
+ servers[i].comment);
+ if (comment) {
+ return false;
+ }
}
}
}
SIVAL(p,6,0);
} else {
SIVAL(p,6,PTR_DIFF(p2,*rdata));
- standard_sub_conn(conn,comment,sizeof(comment));
- StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
- p2 = skip_string(p2,1);
+ comment = talloc_sub_advanced(ctx,
+ lp_servicename(SNUM(conn)),
+ conn->user,
+ conn->connectpath,
+ conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ comment);
+ if (comment) {
+ return false;
+ }
+ if (mdrcnt - struct_len <= 0) {
+ return false;
+ }
+ push_ascii(p2,
+ comment,
+ MIN(mdrcnt - struct_len,
+ MAX_SERVER_STRING_LENGTH),
+ STR_TERMINATE);
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
}
}
*rdata_len = PTR_DIFF(p2,*rdata);
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVAL(*rparam,0,NERR_Success);
SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,*rdata_len);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
char *p2;
- int level = SVAL(p,0);
+ char *endp;
+ int level = get_safe_SVAL(param,tpscnt,p,0,-1);
+
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
DEBUG(4,("NetWkstaGetInfo level %d\n",level));
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
/* check it's a supported varient */
if (!(level==10 && strcsequal(str1,"WrLh") && strcsequal(str2,"zzzBBzz"))) {
}
*rdata_len = mdrcnt + 1024;
- *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
+ *rdata = smb_realloc_limit(*rdata,*rdata_len);
+ if (!*rdata) {
+ return False;
+ }
SSVAL(*rparam,0,NERR_Success);
SSVAL(*rparam,2,0); /* converter word */
p = *rdata;
- p2 = p + 22;
+ endp = *rdata + *rdata_len;
+
+ p2 = get_safe_ptr(*rdata,*rdata_len,p,22);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* host name */
- pstrcpy(p2,get_local_machine_name());
+ strlcpy(p2,get_local_machine_name(),PTR_DIFF(endp,p2));
strupper_m(p2);
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ 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);
+ strlcpy(p2,current_user_info.smb_name,PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
p += 4;
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
- pstrcpy(p2,lp_workgroup());
+ strlcpy(p2,lp_workgroup(),PTR_DIFF(endp,p2));
strupper_m(p2);
- p2 = skip_string(p2,1);
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
p += 4;
SCVAL(p,0,lp_major_announce_version()); /* system version - e.g 4 in 4.1 */
p += 2;
SIVAL(p,0,PTR_DIFF(p2,*rdata));
- pstrcpy(p2,lp_workgroup()); /* don't know. login domain?? */
- p2 = skip_string(p2,1);
+ strlcpy(p2,lp_workgroup(),PTR_DIFF(endp,p2)); /* don't know. login domain?? */
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
p += 4;
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* don't know */
- pstrcpy(p2,"");
- p2 = skip_string(p2,1);
+ strlcpy(p2,"",PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
p += 4;
*rdata_len = PTR_DIFF(p2,*rdata);
where:
- usri11_name specifies the user name for which information is retireved
+ usri11_name specifies the user name for which information is retrieved
usri11_pad aligns the next data structure element to a word boundary
#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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *UserName = skip_string(param,tpscnt,str2);
+ char *p = skip_string(param,tpscnt,UserName);
+ int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
char *p2;
+ char *endp;
const char *level_string;
/* get NIS home of a previously validated user - simeon */
Don't depend on vuser being non-null !!. JRA */
user_struct *vuser = get_valid_user_struct(vuid);
if(vuser != NULL) {
- DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid,
- vuser->user.unix_name));
+ DEBUG(3,(" Username of UID %d is %s\n",
+ (int)vuser->server_info->uid,
+ vuser->user.unix_name));
+ }
+
+ if (!str1 || !str2 || !UserName || !p) {
+ return False;
}
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
DEBUG(4,("RNetUserGetInfo level=%d\n", uLevel));
-
+
/* check it's a supported variant */
if (strcmp(str1,"zWrLh") != 0) {
return False;
}
*rdata_len = mdrcnt + 1024;
- *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
+ *rdata = smb_realloc_limit(*rdata,*rdata_len);
+ if (!*rdata) {
+ return False;
+ }
SSVAL(*rparam,0,NERR_Success);
SSVAL(*rparam,2,0); /* converter word */
p = *rdata;
- p2 = p + usri11_end;
+ endp = *rdata + *rdata_len;
+ p2 = get_safe_ptr(*rdata,*rdata_len,p,usri11_end);
+ if (!p2) {
+ return False;
+ }
- memset(p,0,21);
+ memset(p,0,21);
fstrcpy(p+usri11_name,UserName); /* 21 bytes - user name */
if (uLevel > 0) {
if (uLevel >= 10) {
SIVAL(p,usri11_comment,PTR_DIFF(p2,p)); /* comment */
- pstrcpy(p2,"Comment");
- p2 = skip_string(p2,1);
+ strlcpy(p2,"Comment",PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,usri11_usr_comment,PTR_DIFF(p2,p)); /* user_comment */
- pstrcpy(p2,"UserComment");
- p2 = skip_string(p2,1);
+ strlcpy(p2,"UserComment",PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ 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);
+ strlcpy(p2,((vuser != NULL) ? vuser->user.full_name : UserName),PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
}
if (uLevel == 11) {
+ const char *homedir = "";
+ if (vuser != NULL) {
+ homedir = pdb_get_homedir(
+ vuser->server_info->sam_account);
+ }
/* modelled after NTAS 3.51 reply */
SSVAL(p,usri11_priv,conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
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);
+ strlcpy(p2, homedir, PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
- pstrcpy(p2,"");
- p2 = skip_string(p2,1);
+ strlcpy(p2,"",PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ 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);
+ strlcpy(p2,"\\\\*",PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ 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);
+ strlcpy(p2,"",PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
SIVALS(p,usri11_max_storage,-1); /* max storage */
SSVAL(p,usri11_units_per_week,168); /* units per week */
/* 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);
+ if (!p2) {
+ return False;
+ }
SSVAL(p,usri11_code_page,0); /* code page */
}
SSVAL(p,42,
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);
+ strlcpy(p2, vuser ? pdb_get_homedir(
+ vuser->server_info->sam_account) : "",
+ PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ 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);
+ strlcpy(p2, vuser ? pdb_get_logon_script(
+ vuser->server_info->sam_account) : "",
+ PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ 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);
+ strlcpy(p2,((vuser != NULL) ? vuser->user.full_name : UserName),PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ 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);
+ strlcpy(p2,"",PTR_DIFF(endp,p2));
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
SIVAL(p,76,0); /* workstations */
SIVAL(p,80,0); /* last_logon */
SIVAL(p,84,0); /* last_logoff */
SSVALS(p,102,-1); /* bad_pw_count */
SSVALS(p,104,-1); /* num_logons */
SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
- pstrcpy(p2,"\\\\%L");
- standard_sub_conn(conn, p2,0);
- p2 = skip_string(p2,1);
+ {
+ TALLOC_CTX *ctx = talloc_tos();
+ int space_rem = *rdata_len - (p2 - *rdata);
+ char *tmp;
+
+ if (space_rem <= 0) {
+ return false;
+ }
+ tmp = talloc_strdup(ctx, "\\\\%L");
+ if (!tmp) {
+ return false;
+ }
+ tmp = talloc_sub_basic(ctx,
+ "",
+ "",
+ tmp);
+ if (!tmp) {
+ return false;
+ }
+
+ push_ascii(p2,
+ tmp,
+ space_rem,
+ STR_TERMINATE);
+ }
+ p2 = skip_string(*rdata,*rdata_len,p2);
+ if (!p2) {
+ return False;
+ }
SSVAL(p,110,49); /* country_code */
SSVAL(p,112,860); /* code page */
}
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
int uLevel;
struct pack_desc desc;
char* name;
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));
+ DEBUG(3,(" Username of UID %d is %s\n",
+ (int)vuser->server_info->uid,
+ vuser->user.unix_name));
}
- uLevel = SVAL(p,0);
- name = p + 2;
+ uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
+ name = get_safe_str_ptr(param,tpscnt,p,2);
+ if (!name) {
+ return False;
+ }
memset((char *)&desc,'\0',sizeof(desc));
return False;
}
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
+ }
}
desc.base = *rdata;
}
PACKS(&desc,"z",lp_workgroup());/* domain */
- PACKS(&desc,"z", vuser && vuser->logon_script ? vuser->logon_script :""); /* script path */
+ PACKS(&desc,"z", vuser ? pdb_get_logon_script(
+ vuser->server_info->sam_account) : ""); /* script path */
PACKI(&desc,"D",0x00000000); /* reserved */
}
*rdata_len = desc.usedlen;
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,desc.neededlen);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *user = skip_string(param,tpscnt,str2);
+ char *resource = skip_string(param,tpscnt,user);
+
+ if (!str1 || !str2 || !user || !resource) {
+ return False;
+ }
+ if (skip_string(param,tpscnt,resource) == NULL) {
+ return False;
+ }
DEBUG(3,("WAccessGetUserPerms user=%s resource=%s\n",user,resource));
/* check it's a supported varient */
}
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,0); /* errorcode */
SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,0x7f); /* permission flags */
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
int uLevel;
int count;
int i;
print_status_struct status;
char *tmpdata=NULL;
- uLevel = SVAL(p,2);
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
+ uLevel = get_safe_SVAL(param,tpscnt,p,2,-1);
memset((char *)&desc,'\0',sizeof(desc));
memset((char *)&status,'\0',sizeof(status));
}
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
+ }
desc.base = *rdata;
desc.buflen = mdrcnt;
} else {
}
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,desc.neededlen);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
+ char *name = p;
int uLevel;
int count;
int i, succnt=0;
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);
+ if (!p) {
+ return False;
+ }
+ uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
count = print_queue_status(snum,&queue,&status);
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
+ }
}
desc.base = *rdata;
desc.buflen = mdrcnt;
*rdata_len = desc.usedlen;
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,succnt);
desc->format = "zzzWWzzzWW";
break;
default:
+ DEBUG(0,("check_printdest_info: invalid level %d\n",
+ uLevel));
return False;
}
- if (strcmp(desc->format,id) != 0) {
+ if (id == NULL || strcmp(desc->format,id) != 0) {
+ DEBUG(0,("check_printdest_info: invalid string %s\n",
+ id ? id : "<NULL>" ));
return False;
}
return True;
}
}
-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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
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);
+ if (!p) {
+ return False;
+ }
+ uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel,PrinterName));
desc.neededlen = 0;
} else {
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
+ }
desc.base = *rdata;
desc.buflen = mdrcnt;
} else {
}
*rparam_len = 6;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,desc.neededlen);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
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_SVAL(param,tpscnt,p,0,-1);
DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel));
}
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
+ }
}
desc.base = *rdata;
*rdata_len = desc.usedlen;
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,succnt);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
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_SVAL(param,tpscnt,p,0,-1);
DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel));
}
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
+ }
}
desc.base = *rdata;
desc.buflen = mdrcnt;
*rdata_len = desc.usedlen;
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,succnt);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
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_SVAL(param,tpscnt,p,0,-1);
DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel));
}
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
+ }
}
desc.base = *rdata;
desc.buflen = mdrcnt;
*rdata_len = desc.usedlen;
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,succnt);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
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_SVAL(param,tpscnt,p,0,-1);
DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel));
}
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
+ }
}
memset((char *)&desc,'\0',sizeof(desc));
desc.base = *rdata;
*rdata_len = desc.usedlen;
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,succnt);
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_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
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_SVAL(param,tpscnt,p,0,-1);
DEBUG(3,("RNetSessionEnum uLevel=%d\n",uLevel));
DEBUG(7,("RNetSessionEnum req string=%s\n",str1));
return False;
}
- num_sessions = list_sessions(&session_list);
+ num_sessions = list_sessions(talloc_tos(), &session_list);
if (mdrcnt > 0) {
- *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
+ }
}
memset((char *)&desc,'\0',sizeof(desc));
desc.base = *rdata;
*rdata_len = desc.usedlen;
*rparam_len = 8;
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0); /* converter */
SSVAL(*rparam,4,num_sessions); /* count */
The buffer was too small.
****************************************************************************/
-static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param, char *data,
+static bool api_TooSmall(connection_struct *conn,uint16 vuid, char *param, char *data,
int mdrcnt, int mprcnt,
char **rdata, char **rparam,
int *rdata_len, int *rparam_len)
{
*rparam_len = MIN(*rparam_len,mprcnt);
- *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
*rdata_len = 0;
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);
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
*rdata_len = 0;
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? */
+ bool auth_user; /* Deny anonymous access? */
} api_commands[] = {
{"RNetShareEnum", RAP_WshareEnum, api_RNetShareEnum, True},
{"RNetShareGetInfo", RAP_WshareGetInfo, api_RNetShareGetInfo},
/****************************************************************************
- Handle remote api calls
- ****************************************************************************/
+ Handle remote api calls.
+****************************************************************************/
-int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
- int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
+void api_reply(connection_struct *conn, uint16 vuid,
+ struct smb_request *req,
+ char *data, char *params,
+ int tdscnt, int tpscnt,
+ int mdrcnt, int mprcnt)
{
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;
+ bool reply=False;
int i;
if (!params) {
DEBUG(0,("ERROR: NULL params in api_reply()\n"));
- return 0;
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
}
+ if (tpscnt < 2) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
api_command = SVAL(params,0);
+ /* Is there a string at position params+2 ? */
+ if (skip_string(params,tpscnt,params+2)) {
+ name1 = params + 2;
+ } else {
+ name1 = "";
+ }
+ name2 = skip_string(params,tpscnt,params+2);
+ 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++) {
user_struct *user = get_valid_user_struct(vuid);
if (!user || user->guest) {
- return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return;
}
}
DEBUG(0,("api_reply: malloc fail !\n"));
SAFE_FREE(rdata);
SAFE_FREE(rparam);
- return -1;
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
- 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);
/* if we get False back then it's actually unsupported */
if (!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);
}
- send_trans_reply(outbuf, rparam, rparam_len, rdata, rdata_len, False);
+ /* If api_Unsupported returns false we can't return anything. */
+ if (reply) {
+ send_trans_reply(conn, req, rparam, rparam_len,
+ rdata, rdata_len, False);
+ }
SAFE_FREE(rdata);
SAFE_FREE(rparam);
- return -1;
+ return;
}