r12163: Change lookup_sid and lookup_name to return const char * instead of char *,
[samba.git] / source3 / smbd / lanman.c
index 619ecd736aa3a4232b182d2273ecd42ea878919f..4778702e7acd96e96c65bca15eccad297ee10894 100644 (file)
 
 #include "includes.h"
 
+extern struct current_user current_user;
+extern userdom_struct current_user_info;
+
 #ifdef CHECK_TYPES
 #undef CHECK_TYPES
 #endif
 #define CHECK_TYPES 0
 
-extern fstring local_machine;
-extern pstring global_myname;
-extern fstring global_myworkgroup;
-
 #define NERR_Success 0
 #define NERR_badpass 86
 #define NERR_notsupported 50
@@ -51,57 +50,65 @@ extern fstring global_myworkgroup;
 
 #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,
-                        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, 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,
+                        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)
+                       int snum, char **dst, char *src, int *n)
 {
        pstring buf;
        int l;
 
-       if (!src || !dst || !n || !(*dst)) return(0);
+       if (!src || !dst || !n || !(*dst)) {
+               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-1, STR_TERMINATE);
+       l = push_ascii(*dst,buf,*n, STR_TERMINATE);
        (*dst) += l;
        (*n) -= l;
        return l;
 }
 
-static int CopyAndAdvance(char** dst, char* src, int* n)
+static int CopyAndAdvance(char **dst, char *src, int *n)
 {
-  int l;
-  if (!src || !dst || !n || !(*dst)) return(0);
-  l = push_ascii(*dst,src,*n, STR_TERMINATE);
-  (*dst) += l;
-  (*n) -= l;
-  return l;
+       int l;
+       if (!src || !dst || !n || !(*dst)) {
+               return 0;
+       }
+       l = push_ascii(*dst,src,*n, STR_TERMINATE);
+       (*dst) += l;
+       (*n) -= l;
+       return l;
 }
 
-static int StrlenExpanded(connection_struct *conn, int snum, chars)
+static int StrlenExpanded(connection_struct *conn, int snum, char *s)
 {
        pstring buf;
-       if (!s) return(0);
+       if (!s) {
+               return 0;
+       }
        StrnCpy(buf,s,sizeof(buf)/2);
        pstring_sub(buf,"%S",lp_servicename(snum));
        standard_sub_conn(conn,buf,sizeof(buf));
        return strlen(buf) + 1;
 }
 
-static char* Expand(connection_struct *conn, int snum, char* s)
+static char *Expand(connection_struct *conn, int snum, char *s)
 {
        static pstring buf;
-       if (!s) return(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));
@@ -109,218 +116,248 @@ static char* Expand(connection_struct *conn, int snum, char* s)
 }
 
 /*******************************************************************
-  check a API string for validity when we only need to check the prefix
-  ******************************************************************/
-static BOOL prefix_ok(char *str,char *prefix)
+ Check a API string for validity when we only need to check the prefix.
+******************************************************************/
+
+static BOOL prefix_ok(const char *str, const char *prefix)
 {
-  return(strncmp(str,prefix,strlen(prefix)) == 0);
+       return(strncmp(str,prefix,strlen(prefix)) == 0);
 }
 
 struct pack_desc {
-  char* format;            /* formatstring for structure */
-  char* subformat;  /* subformat for structure */
-  char* base;      /* baseaddress of buffer */
-  int buflen;     /* remaining size for fixed part; on init: length of base */
-  int subcount;            /* count of substructures */
-  char* structbuf;  /* pointer into buffer for remaining fixed part */
-  int stringlen;    /* remaining size for variable part */             
-  char* stringbuf;  /* pointer into buffer for remaining variable part */
-  int neededlen;    /* total needed size */
-  int usedlen;     /* total used size (usedlen <= neededlen and usedlen <= buflen) */
-  char* curpos;            /* current position; pointer into format or subformat */
-  int errcode;
+       const char *format;         /* formatstring for structure */
+       const char *subformat;  /* subformat for structure */
+       char *base;         /* baseaddress of buffer */
+       int buflen;        /* remaining size for fixed part; on init: length of base */
+       int subcount;       /* count of substructures */
+       char *structbuf;  /* pointer into buffer for remaining fixed part */
+       int stringlen;    /* remaining size for variable part */                
+       char *stringbuf;  /* pointer into buffer for remaining variable part */
+       int neededlen;    /* total needed size */
+       int usedlen;        /* total used size (usedlen <= neededlen and usedlen <= buflen) */
+       const char *curpos;         /* current position; pointer into format or subformat */
+       int errcode;
 };
 
-static int get_counter(char** p)
+static int get_counter(const char **p)
 {
-  int i, n;
-  if (!p || !(*p)) return(1);
-  if (!isdigit((int)**p)) return 1;
-  for (n = 0;;) {
-    i = **p;
-    if (isdigit(i))
-      n = 10 * n + (i - '0');
-    else
-      return n;
-    (*p)++;
-  }
+       int i, n;
+       if (!p || !(*p)) {
+               return 1;
+       }
+       if (!isdigit((int)**p)) {
+               return 1;
+       }
+       for (n = 0;;) {
+               i = **p;
+               if (isdigit(i)) {
+                       n = 10 * n + (i - '0');
+               } else {
+                       return n;
+               }
+               (*p)++;
+       }
 }
 
-static int getlen(char* p)
+static int getlen(const char *p)
 {
-  int n = 0;
-  if (!p) return(0);
-  while (*p) {
-    switch( *p++ ) {
-    case 'W':                  /* word (2 byte) */
-      n += 2;
-      break;
-    case 'K':                  /* status word? (2 byte) */
-      n += 2;
-      break;
-    case 'N':                  /* count of substructures (word) at end */
-      n += 2;
-      break;
-    case 'D':                  /* double word (4 byte) */
-    case 'z':                  /* offset to zero terminated string (4 byte) */
-    case 'l':                  /* offset to user data (4 byte) */
-      n += 4;
-      break;
-    case 'b':                  /* offset to data (with counter) (4 byte) */
-      n += 4;
-      get_counter(&p);
-      break;
-    case 'B':                  /* byte (with optional counter) */
-      n += get_counter(&p);
-      break;
-    }
-  }
-  return n;
+       int n = 0;
+       if (!p) {
+               return 0;
+       }
+
+       while (*p) {
+               switch( *p++ ) {
+               case 'W':                       /* word (2 byte) */
+                       n += 2;
+                       break;
+               case 'K':                       /* status word? (2 byte) */
+                       n += 2;
+                       break;
+               case 'N':                       /* count of substructures (word) at end */
+                       n += 2;
+                       break;
+               case 'D':                       /* double word (4 byte) */
+               case 'z':                       /* offset to zero terminated string (4 byte) */
+               case 'l':                       /* offset to user data (4 byte) */
+                       n += 4;
+                       break;
+               case 'b':                       /* offset to data (with counter) (4 byte) */
+                       n += 4;
+                       get_counter(&p);
+                       break;
+               case 'B':                       /* byte (with optional counter) */
+                       n += get_counter(&p);
+                       break;
+               }
+       }
+       return n;
 }
 
-static BOOL init_package(struct pack_descp, int count, int subcount)
+static BOOL init_package(struct pack_desc *p, int count, int subcount)
 {
-  int n = p->buflen;
-  int i;
+       int n = p->buflen;
+       int i;
 
-  if (!p->format || !p->base) return(False);
-
-  i = count * getlen(p->format);
-  if (p->subformat) i += subcount * getlen(p->subformat);
-  p->structbuf = p->base;
-  p->neededlen = 0;
-  p->usedlen = 0;
-  p->subcount = 0;
-  p->curpos = p->format;
-  if (i > n) {
-    p->neededlen = i;
-    i = n = 0;
+       if (!p->format || !p->base) {
+               return False;
+       }
+
+       i = count * getlen(p->format);
+       if (p->subformat) {
+               i += subcount * getlen(p->subformat);
+       }
+       p->structbuf = p->base;
+       p->neededlen = 0;
+       p->usedlen = 0;
+       p->subcount = 0;
+       p->curpos = p->format;
+       if (i > n) {
+               p->neededlen = i;
+               i = n = 0;
 #if 0
-    /*
-     * This is the old error code we used. Aparently
-     * WinNT/2k systems return ERRbuftoosmall (2123) and
-     * OS/2 needs this. I'm leaving this here so we can revert
-     * if needed. JRA.
-     */
-    p->errcode = ERRmoredata;
+               /*
+                * This is the old error code we used. Aparently
+                * WinNT/2k systems return ERRbuftoosmall (2123) and
+                * OS/2 needs this. I'm leaving this here so we can revert
+                * if needed. JRA.
+                */
+               p->errcode = ERRmoredata;
 #else
-       p->errcode = ERRbuftoosmall;
+               p->errcode = ERRbuftoosmall;
 #endif
-  }
-  else
-    p->errcode = NERR_Success;
-  p->buflen = i;
-  n -= i;
-  p->stringbuf = p->base + i;
-  p->stringlen = n;
-  return(p->errcode == NERR_Success);
+       } else {
+               p->errcode = NERR_Success;
+       }
+       p->buflen = i;
+       n -= i;
+       p->stringbuf = p->base + i;
+       p->stringlen = n;
+       return (p->errcode == NERR_Success);
 }
 
-static int package(struct pack_descp, ...)
+static int package(struct pack_desc *p, ...)
 {
-  va_list args;
-  int needed=0, stringneeded;
-  char* str=NULL;
-  int is_string=0, stringused;
-  int32 temp;
+       va_list args;
+       int needed=0, stringneeded;
+       const char *str=NULL;
+       int is_string=0, stringused;
+       int32 temp;
 
-  va_start(args,p);
+       va_start(args,p);
 
-  if (!*p->curpos) {
-    if (!p->subcount)
-      p->curpos = p->format;
-    else {
-      p->curpos = p->subformat;
-      p->subcount--;
-    }
-  }
+       if (!*p->curpos) {
+               if (!p->subcount) {
+                       p->curpos = p->format;
+               } else {
+                       p->curpos = p->subformat;
+                       p->subcount--;
+               }
+       }
 #if CHECK_TYPES
-  str = va_arg(args,char*);
-  SMB_ASSERT(strncmp(str,p->curpos,strlen(str)) == 0);
+       str = va_arg(args,char*);
+       SMB_ASSERT(strncmp(str,p->curpos,strlen(str)) == 0);
 #endif
-  stringneeded = -1;
+       stringneeded = -1;
 
-  if (!p->curpos) {
-    va_end(args);
-    return(0);
-  }
+       if (!p->curpos) {
+               va_end(args);
+               return 0;
+       }
 
-  switch( *p->curpos++ ) {
-  case 'W':                    /* word (2 byte) */
-    needed = 2;
-    temp = va_arg(args,int);
-    if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
-    break;
-  case 'K':                    /* status word? (2 byte) */
-    needed = 2;
-    temp = va_arg(args,int);
-    if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
-    break;
-  case 'N':                    /* count of substructures (word) at end */
-    needed = 2;
-    p->subcount = va_arg(args,int);
-    if (p->buflen >= needed) SSVAL(p->structbuf,0,p->subcount);
-    break;
-  case 'D':                    /* double word (4 byte) */
-    needed = 4;
-    temp = va_arg(args,int);
-    if (p->buflen >= needed) SIVAL(p->structbuf,0,temp);
-    break;
-  case 'B':                    /* byte (with optional counter) */
-    needed = get_counter(&p->curpos);
-    {
-      char *s = va_arg(args,char*);
-      if (p->buflen >= needed) StrnCpy(p->structbuf,s?s:"",needed-1);
-    }
-    break;
-  case 'z':                    /* offset to zero terminated string (4 byte) */
-    str = va_arg(args,char*);
-    stringneeded = (str ? strlen(str)+1 : 0);
-    is_string = 1;
-    break;
-  case 'l':                    /* offset to user data (4 byte) */
-    str = va_arg(args,char*);
-    stringneeded = va_arg(args,int);
-    is_string = 0;
-    break;
-  case 'b':                    /* offset to data (with counter) (4 byte) */
-    str = va_arg(args,char*);
-    stringneeded = get_counter(&p->curpos);
-    is_string = 0;
-    break;
-  }
-  va_end(args);
-  if (stringneeded >= 0) {
-    needed = 4;
-    if (p->buflen >= needed) {
-      stringused = stringneeded;
-      if (stringused > p->stringlen) {
-       stringused = (is_string ? p->stringlen : 0);
-       if (p->errcode == NERR_Success) p->errcode = ERRmoredata;
-      }
-      if (!stringused)
-       SIVAL(p->structbuf,0,0);
-      else {
-       SIVAL(p->structbuf,0,PTR_DIFF(p->stringbuf,p->base));
-       memcpy(p->stringbuf,str?str:"",stringused);
-       if (is_string) p->stringbuf[stringused-1] = '\0';
-       p->stringbuf += stringused;
-       p->stringlen -= stringused;
-       p->usedlen += stringused;
-      }
-    }
-    p->neededlen += stringneeded;
-  }
-  p->neededlen += needed;
-  if (p->buflen >= needed) {
-    p->structbuf += needed;
-    p->buflen -= needed;
-    p->usedlen += needed;
-  }
-  else {
-    if (p->errcode == NERR_Success) p->errcode = ERRmoredata;
-  }
-  return 1;
+       switch( *p->curpos++ ) {
+               case 'W':                       /* word (2 byte) */
+                       needed = 2;
+                       temp = va_arg(args,int);
+                       if (p->buflen >= needed) {
+                               SSVAL(p->structbuf,0,temp);
+                       }
+                       break;
+               case 'K':                       /* status word? (2 byte) */
+                       needed = 2;
+                       temp = va_arg(args,int);
+                       if (p->buflen >= needed) {
+                               SSVAL(p->structbuf,0,temp);
+                       }
+                       break;
+               case 'N':                       /* count of substructures (word) at end */
+                       needed = 2;
+                       p->subcount = va_arg(args,int);
+                       if (p->buflen >= needed) {
+                               SSVAL(p->structbuf,0,p->subcount);
+                       }
+                       break;
+               case 'D':                       /* double word (4 byte) */
+                       needed = 4;
+                       temp = va_arg(args,int);
+                       if (p->buflen >= needed) {
+                               SIVAL(p->structbuf,0,temp);
+                       }
+                       break;
+               case 'B':                       /* byte (with optional counter) */
+                       needed = get_counter(&p->curpos);
+                       {
+                               char *s = va_arg(args,char*);
+                               if (p->buflen >= needed) {
+                                       StrnCpy(p->structbuf,s?s:"",needed-1);
+                               }
+                       }
+                       break;
+               case 'z':                       /* offset to zero terminated string (4 byte) */
+                       str = va_arg(args,char*);
+                       stringneeded = (str ? strlen(str)+1 : 0);
+                       is_string = 1;
+                       break;
+               case 'l':                       /* offset to user data (4 byte) */
+                       str = va_arg(args,char*);
+                       stringneeded = va_arg(args,int);
+                       is_string = 0;
+                       break;
+               case 'b':                       /* offset to data (with counter) (4 byte) */
+                       str = va_arg(args,char*);
+                       stringneeded = get_counter(&p->curpos);
+                       is_string = 0;
+                       break;
+       }
+
+       va_end(args);
+       if (stringneeded >= 0) {
+               needed = 4;
+               if (p->buflen >= needed) {
+                       stringused = stringneeded;
+                       if (stringused > p->stringlen) {
+                               stringused = (is_string ? p->stringlen : 0);
+                               if (p->errcode == NERR_Success) {
+                                       p->errcode = ERRmoredata;
+                               }
+                       }
+                       if (!stringused) {
+                               SIVAL(p->structbuf,0,0);
+                       } else {
+                               SIVAL(p->structbuf,0,PTR_DIFF(p->stringbuf,p->base));
+                               memcpy(p->stringbuf,str?str:"",stringused);
+                               if (is_string) {
+                                       p->stringbuf[stringused-1] = '\0';
+                               }
+                               p->stringbuf += stringused;
+                               p->stringlen -= stringused;
+                               p->usedlen += stringused;
+                       }
+               }
+               p->neededlen += stringneeded;
+       }
+
+       p->neededlen += needed;
+       if (p->buflen >= needed) {
+               p->structbuf += needed;
+               p->buflen -= needed;
+               p->usedlen += needed;
+       } else {
+               if (p->errcode == NERR_Success) {
+                       p->errcode = ERRmoredata;
+               }
+       }
+       return 1;
 }
 
 #if CHECK_TYPES
@@ -331,67 +368,72 @@ static int package(struct pack_desc* p, ...)
 #define PACKl(desc,t,v,l) package(desc,v,l)
 #endif
 
-static void PACKI(struct pack_desc* desc,char *t,int v)
+static void PACKI(struct pack_desc* desc, const char *t,int v)
 {
-  PACK(desc,t,v);
+       PACK(desc,t,v);
 }
 
-static void PACKS(struct pack_desc* desc,char *t,char *v)
+static void PACKS(struct pack_desc* desc,const char *t,const char *v)
 {
-  PACK(desc,t,v);
+       PACK(desc,t,v);
 }
 
-
 /****************************************************************************
-  get a print queue
-  ****************************************************************************/
+ Get a print queue.
+****************************************************************************/
+
 static void PackDriverData(struct pack_desc* desc)
 {
-  char drivdata[4+4+32];
-  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);
-  PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
+       char drivdata[4+4+32];
+       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);
+       PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
 }
 
 static int check_printq_info(struct pack_desc* desc,
-                            int uLevel, char *id1, char *id2)
+                               unsigned int uLevel, char *id1, char *id2)
 {
-  desc->subformat = NULL;
-  switch( uLevel ) {
-  case 0:
-    desc->format = "B13";
-    break;
-  case 1:
-    desc->format = "B13BWWWzzzzzWW";
-    break;
-  case 2:
-    desc->format = "B13BWWWzzzzzWN";
-    desc->subformat = "WB21BB16B10zWWzDDz";
-    break;
-  case 3:
-    desc->format = "zWWWWzzzzWWzzl";
-    break;
-  case 4:
-    desc->format = "zWWWWzzzzWNzzl";
-    desc->subformat = "WWzWWDDzz";
-    break;
-  case 5:
-    desc->format = "z";
-    break;
-  case 51:
-    desc->format = "K";
-    break;
-  case 52:
-    desc->format = "WzzzzzzzzN";
-    desc->subformat = "z";
-    break;
-  default: return False;
-  }
-  if (strcmp(desc->format,id1) != 0) return False;
-  if (desc->subformat && strcmp(desc->subformat,id2) != 0) return False;
-  return True;
+       desc->subformat = NULL;
+       switch( uLevel ) {
+               case 0:
+                       desc->format = "B13";
+                       break;
+               case 1:
+                       desc->format = "B13BWWWzzzzzWW";
+                       break;
+               case 2:
+                       desc->format = "B13BWWWzzzzzWN";
+                       desc->subformat = "WB21BB16B10zWWzDDz";
+                       break;
+               case 3:
+                       desc->format = "zWWWWzzzzWWzzl";
+                       break;
+               case 4:
+                       desc->format = "zWWWWzzzzWNzzl";
+                       desc->subformat = "WWzWWDDzz";
+                       break;
+               case 5:
+                       desc->format = "z";
+                       break;
+               case 51:
+                       desc->format = "K";
+                       break;
+               case 52:
+                       desc->format = "WzzzzzzzzN";
+                       desc->subformat = "z";
+                       break;
+               default:
+                       return False;
+       }
+       if (strcmp(desc->format,id1) != 0) {
+               return False;
+       }
+       if (desc->subformat && strcmp(desc->subformat,id2) != 0) {
+               return False;
+       }
+       return True;
 }
 
 
@@ -435,66 +477,66 @@ static int printq_status(int v)
 }
 
 static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
-                              struct pack_descdesc,
-                              print_queue_structqueue, int n)
+                              struct pack_desc *desc,
+                              print_queue_struct *queue, int n)
 {
-  time_t t = queue->time;
-
-  /* the client expects localtime */
-  t -= TimeDiff(t);
-
-  PACKI(desc,"W",pjobid_to_rap(queue->job)); /* uJobId */
-  if (uLevel == 1) {
-    PACKS(desc,"B21",queue->fs_user); /* szUserName */
-    PACKS(desc,"B","");                /* pad */
-    PACKS(desc,"B16","");      /* szNotifyName */
-    PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
-    PACKS(desc,"z","");                /* pszParms */
-    PACKI(desc,"W",n+1);               /* uPosition */
-    PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */
-    PACKS(desc,"z","");                /* pszStatus */
-    PACKI(desc,"D",t); /* ulSubmitted */
-    PACKI(desc,"D",queue->size); /* ulSize */
-    PACKS(desc,"z",queue->fs_file); /* pszComment */
-  }
-  if (uLevel == 2 || uLevel == 3 || uLevel == 4) {
-    PACKI(desc,"W",queue->priority);           /* uPriority */
-    PACKS(desc,"z",queue->fs_user); /* pszUserName */
-    PACKI(desc,"W",n+1);               /* uPosition */
-    PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */
-    PACKI(desc,"D",t); /* ulSubmitted */
-    PACKI(desc,"D",queue->size); /* ulSize */
-    PACKS(desc,"z","Samba");   /* pszComment */
-    PACKS(desc,"z",queue->fs_file); /* pszDocument */
-    if (uLevel == 3) {
-      PACKS(desc,"z","");      /* pszNotifyName */
-      PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */
-      PACKS(desc,"z","");      /* pszParms */
-      PACKS(desc,"z","");      /* pszStatus */
-      PACKS(desc,"z",SERVICE(snum)); /* pszQueue */
-      PACKS(desc,"z","lpd");   /* pszQProcName */
-      PACKS(desc,"z","");      /* pszQProcParms */
-      PACKS(desc,"z","NULL"); /* pszDriverName */
-      PackDriverData(desc);    /* pDriverData */
-      PACKS(desc,"z","");      /* pszPrinterName */
-    } else if (uLevel == 4) {   /* OS2 */
-      PACKS(desc,"z","");       /* pszSpoolFileName  */
-       PACKS(desc,"z","");       /* pszPortName       */
-       PACKS(desc,"z","");       /* pszStatus         */
-       PACKI(desc,"D",0);        /* ulPagesSpooled    */
-       PACKI(desc,"D",0);        /* ulPagesSent       */
-       PACKI(desc,"D",0);        /* ulPagesPrinted    */
-       PACKI(desc,"D",0);        /* ulTimePrinted     */
-       PACKI(desc,"D",0);        /* ulExtendJobStatus */
-       PACKI(desc,"D",0);        /* ulStartPage       */
-       PACKI(desc,"D",0);        /* ulEndPage         */
-    }
-  }
+       time_t t = queue->time;
+
+       /* the client expects localtime */
+       t -= get_time_zone(t);
+
+       PACKI(desc,"W",pjobid_to_rap(lp_const_servicename(snum),queue->job)); /* uJobId */
+       if (uLevel == 1) {
+               PACKS(desc,"B21",queue->fs_user); /* szUserName */
+               PACKS(desc,"B","");             /* pad */
+               PACKS(desc,"B16","");   /* szNotifyName */
+               PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
+               PACKS(desc,"z","");             /* pszParms */
+               PACKI(desc,"W",n+1);            /* uPosition */
+               PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */
+               PACKS(desc,"z","");             /* pszStatus */
+               PACKI(desc,"D",t); /* ulSubmitted */
+               PACKI(desc,"D",queue->size); /* ulSize */
+               PACKS(desc,"z",queue->fs_file); /* pszComment */
+       }
+       if (uLevel == 2 || uLevel == 3 || uLevel == 4) {
+               PACKI(desc,"W",queue->priority);                /* uPriority */
+               PACKS(desc,"z",queue->fs_user); /* pszUserName */
+               PACKI(desc,"W",n+1);            /* uPosition */
+               PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */
+               PACKI(desc,"D",t); /* ulSubmitted */
+               PACKI(desc,"D",queue->size); /* ulSize */
+               PACKS(desc,"z","Samba");        /* pszComment */
+               PACKS(desc,"z",queue->fs_file); /* pszDocument */
+               if (uLevel == 3) {
+                       PACKS(desc,"z","");     /* pszNotifyName */
+                       PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */
+                       PACKS(desc,"z","");     /* pszParms */
+                       PACKS(desc,"z","");     /* pszStatus */
+                       PACKS(desc,"z",SERVICE(snum)); /* pszQueue */
+                       PACKS(desc,"z","lpd");  /* pszQProcName */
+                       PACKS(desc,"z","");     /* pszQProcParms */
+                       PACKS(desc,"z","NULL"); /* pszDriverName */
+                       PackDriverData(desc);   /* pDriverData */
+                       PACKS(desc,"z","");     /* pszPrinterName */
+               } else if (uLevel == 4) {   /* OS2 */
+                       PACKS(desc,"z","");       /* pszSpoolFileName  */
+                       PACKS(desc,"z","");       /* pszPortName       */
+                       PACKS(desc,"z","");       /* pszStatus         */
+                       PACKI(desc,"D",0);        /* ulPagesSpooled    */
+                       PACKI(desc,"D",0);        /* ulPagesSent       */
+                       PACKI(desc,"D",0);        /* ulPagesPrinted    */
+                       PACKI(desc,"D",0);        /* ulTimePrinted     */
+                       PACKI(desc,"D",0);        /* ulExtendJobStatus */
+                       PACKI(desc,"D",0);        /* ulStartPage       */
+                       PACKI(desc,"D",0);        /* ulEndPage         */
+               }
+       }
 }
 
 /********************************************************************
  Return a driver name given an snum.
Looks in a tdb first. Returns True if from tdb, False otherwise.
+ Returns True if from tdb, False otherwise.
  ********************************************************************/
 
 static BOOL get_driver_name(int snum, pstring drivername)
@@ -502,13 +544,11 @@ static BOOL get_driver_name(int snum, pstring drivername)
        NT_PRINTER_INFO_LEVEL *info = NULL;
        BOOL in_tdb = False;
 
-       get_a_printer (&info, 2, lp_servicename(snum));
+       get_a_printer (NULL, &info, 2, lp_servicename(snum));
        if (info != NULL) {
                pstrcpy( drivername, info->info_2->drivername);
                in_tdb = True;
                free_a_printer(&info, 2);
-       } else {
-               pstrcpy( drivername, lp_printerdriver(snum));
        }
 
        return in_tdb;
@@ -518,162 +558,84 @@ static BOOL get_driver_name(int snum, pstring drivername)
  Respond to the DosPrintQInfo command with a level of 52
  This is used to get printer driver information for Win9x clients
  ********************************************************************/
-static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
-                               struct pack_desc* desc,
-                               int count, print_queue_struct* queue,
-                               print_status_struct* status)
+static void fill_printq_info_52(connection_struct *conn, int snum, 
+                               struct pack_desc* desc, int count )
 {
-       int i;
-       BOOL ok = False;
-       pstring tok,driver,datafile,langmon,helpfile,datatype;
-       char *p;
-       char **lines = NULL;
-       pstring gen_line;
-       BOOL in_tdb = False;
-       fstring location;
-       pstring drivername;
-
-       /*
-        * Check in the tdb *first* before checking the legacy
-        * files. This allows an NT upload to take precedence over
-        * the existing fileset. JRA.
-        * 
-        * we need to lookup the driver name prior to making the call
-        * to get_a_printer_driver_9x_compatible() and not rely on the
-        * 'print driver' parameter --jerry
-        */
+       int                             i;
+       fstring                         location;
+       NT_PRINTER_DRIVER_INFO_LEVEL    driver;
+       NT_PRINTER_INFO_LEVEL           *printer = NULL;
 
+       ZERO_STRUCT(driver);
 
-       if ((get_driver_name(snum,drivername)) && 
-           ((ok = get_a_printer_driver_9x_compatible(gen_line, drivername)) == True))
-       {
-               in_tdb = True;
-               p = gen_line;
-               DEBUG(10,("9x compatable driver line for [%s]: [%s]\n", drivername, gen_line));
-       } 
-       else 
-       {
-               /* didn't find driver in tdb */
-
-               DEBUG(10,("snum: %d\nprinterdriver: [%s]\nlp_driverfile: [%s]\n",
-                          snum, drivername, lp_driverfile(snum)));
-
-               lines = file_lines_load(lp_driverfile(snum),NULL);
-               if (!lines) 
-               {
-                       DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),
-                                 strerror(errno)));
-                       desc->errcode=NERR_notsupported;
-                       goto done;
-               } 
-
-               /* lookup the long printer driver name in the file description */
-               for (i=0;lines[i] && !ok;i++) 
-               {
-                       p = lines[i];
-                       if (next_token(&p,tok,":",sizeof(tok)) &&
-                          (strlen(drivername) == strlen(tok)) &&
-                          (!strncmp(tok,drivername,strlen(drivername))))
-                       {
-                               ok = True;
-                       }
-               }
+       if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
+               DEBUG(3,("fill_printq_info_52: Failed to lookup printer [%s]\n", 
+                       lp_servicename(snum)));
+               goto err;
        }
-
-       if (ok)
+               
+       if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, 
+               "Windows 4.0", 0)) )
        {
-               /* driver file name */
-               if (!next_token(&p,driver,":",sizeof(driver)))
-                       goto err;
-
-               /* data file name */
-               if (!next_token(&p,datafile,":",sizeof(datafile)))
-                       goto err;
+               DEBUG(3,("fill_printq_info_52: Failed to lookup driver [%s]\n", 
+                       printer->info_2->drivername));
+               goto err;
+       }
 
-               /*
-                * for the next tokens - which may be empty - I have
-                * to check for empty tokens first because the
-                * next_token function will skip all empty token
-                * fields */
-
-               /* help file */
-               if (*p == ':') 
-               {
-                       *helpfile = '\0';
-                       p++;
-               } 
-               else if (!next_token(&p,helpfile,":",sizeof(helpfile)))
-                       goto err;
+       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);
        
-               /* language monitor */
-               if (*p == ':') 
-               {
-                       *langmon = '\0';
-                       p++;
-               } 
-               else if (!next_token(&p,langmon,":",sizeof(langmon)))
-                       goto err;
+       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 */
        
-               /* default data type */
-               if (!next_token(&p,datatype,":",sizeof(datatype))) 
-                       goto err;
+       fstrcpy(location, "\\\\%L\\print$\\WIN40\\0");
+       standard_sub_basic( "", location, sizeof(location)-1 );
+       PACKS(desc,"z", location);                          /* share to retrieve files */
        
-               PACKI(desc,"W",0x0400);               /* don't know */
-               PACKS(desc,"z",drivername);    /* long printer name */
-               PACKS(desc,"z",driver);                    /* Driverfile Name */
-               PACKS(desc,"z",datafile);                  /* Datafile name */
-               PACKS(desc,"z",langmon);                         /* language monitor */
-               if (in_tdb)
-               {
-                       fstrcpy(location, "\\\\");
-                       fstrcat(location, global_myname);
-                       fstrcat(location, "\\print$\\WIN40\\0");
-                       PACKS(desc,"z",location);   /* share to retrieve files */
-               }
-               else
-               {
-                       PACKS(desc,"z",lp_driverlocation(snum));   /* share to retrieve files */
-               }
-               PACKS(desc,"z",datatype);                        /* default data type */
-               PACKS(desc,"z",helpfile);                  /* helpfile name */
-               PACKS(desc,"z",driver);                    /* driver name */
-
-               DEBUG(3,("printerdriver:%s:\n",drivername));
-               DEBUG(3,("Driver:%s:\n",driver));
-               DEBUG(3,("Data File:%s:\n",datafile));
-               DEBUG(3,("Language Monitor:%s:\n",langmon));
-               if (in_tdb)
-                       DEBUG(3,("lp_driverlocation:%s:\n",location));
-               else
-                       DEBUG(3,("lp_driverlocation:%s:\n",lp_driverlocation(snum)));
-               DEBUG(3,("Data Type:%s:\n",datatype));
-               DEBUG(3,("Help File:%s:\n",helpfile));
-               PACKI(desc,"N",count);                     /* number of files to copy */
-
-               for (i=0;i<count;i++) 
-               {
-                       /* no need to check return value here
-                        * - it was already tested in
-                        * get_printerdrivernumber */
-                       next_token(&p,tok,",",sizeof(tok));
-                       PACKS(desc,"z",tok);         /* driver files to copy */
-                       DEBUG(3,("file:%s:\n",tok));
-               }
-               
-               DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
-                         SERVICE(snum),count));
-
-               desc->errcode=NERR_Success;
-               goto done;
+       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 */
+
+       DEBUG(3,("Printer Driver Name: %s:\n",driver.info_3->name));
+       DEBUG(3,("Driver: %s:\n",driver.info_3->driverpath));
+       DEBUG(3,("Data File: %s:\n",driver.info_3->datafile));
+       DEBUG(3,("Language Monitor: %s:\n",driver.info_3->monitorname));
+       DEBUG(3,("Driver Location: %s:\n",location));
+       DEBUG(3,("Data Type: %s:\n",driver.info_3->defaultdatatype));
+       DEBUG(3,("Help File: %s:\n",driver.info_3->helpfile));
+       PACKI(desc,"N",count);                     /* number of files to copy */
+
+       for ( i=0; i<count && driver.info_3->dependentfiles && *driver.info_3->dependentfiles[i]; i++) 
+       {
+               trim_string(driver.info_3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
+               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));
 
-  err:
+        desc->errcode=NERR_Success;
+       goto done;
 
+err:
        DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
        desc->errcode=NERR_notsupported;
 
- done:
-       file_lines_free(lines); 
+done:
+       if ( printer )
+               free_a_printer( &printer, 2 );
+               
+       if ( driver.info_3 )
+               free_a_printer_driver( driver, 3 );
 }
 
 
@@ -751,88 +713,44 @@ static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
                        fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
        }
 
-       if (uLevel==52) {
-               fill_printq_info_52(conn, snum, uLevel, desc, count, queue, status);
-       }
+       if (uLevel==52)
+               fill_printq_info_52( conn, snum, desc, count );
 }
 
 /* This function returns the number of files for a given driver */
 static int get_printerdrivernumber(int snum)
 {
-       int i, result = 0;
-       BOOL ok = False;
-       pstring tok;
-       char *p;
-       char **lines = NULL;
-       pstring gen_line;
-       pstring drivername;
-       
-       /*
-        * Check in the tdb *first* before checking the legacy
-        * files. This allows an NT upload to take precedence over
-        * the existing fileset. JRA.
-        *
-        * we need to lookup the driver name prior to making the call
-        * to get_a_printer_driver_9x_compatible() and not rely on the
-        * 'print driver' parameter --jerry
-        */
-       
-       if ((get_driver_name(snum,drivername)) && 
-           (ok = get_a_printer_driver_9x_compatible(gen_line, drivername) == True)) 
-       {
-               p = gen_line;
-               DEBUG(10,("9x compatable driver line for [%s]: [%s]\n", drivername, gen_line));
-       } 
-       else 
-       {
-               /* didn't find driver in tdb */
-       
-               DEBUG(10,("snum: %d\nprinterdriver: [%s]\nlp_driverfile: [%s]\n",
-                         snum, drivername, lp_driverfile(snum)));
-               
-               lines = file_lines_load(lp_driverfile(snum), NULL);
-               if (!lines) 
-               {
-                       DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),strerror(errno)));
-                       goto done;
-               } 
-
-               /* lookup the long printer driver name in the file description */
-               for (i=0;lines[i] && !ok;i++) 
-               {
-                       p = lines[i];
-                       if (next_token(&p,tok,":",sizeof(tok)) &&
-                          (strlen(drivername) == strlen(tok)) &&
-                          (!strncmp(tok,drivername,strlen(drivername)))) 
-                       {
-                               ok = True;
-                       }
-               }
+       int                             result = 0;
+       NT_PRINTER_DRIVER_INFO_LEVEL    driver;
+       NT_PRINTER_INFO_LEVEL           *printer = NULL;
+
+       ZERO_STRUCT(driver);
+
+       if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
+               DEBUG(3,("get_printerdrivernumber: Failed to lookup printer [%s]\n", 
+                       lp_servicename(snum)));
+               goto done;
        }
-       
-       if( ok ) 
-       {
-               /* skip 5 fields */
-               i = 5;
-               while (*p && i) {
-                       if (*p++ == ':') i--;
-               }
-               if (!*p || i) {
-                       DEBUG(3,("Can't determine number of printer driver files\n"));
-                       goto done;
-               }
                
-               /* count the number of files */
-               while (next_token(&p,tok,",",sizeof(tok)))
-                       i++;
-       
-               result = i;
+       if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, 
+               "Windows 4.0", 0)) )
+       {
+               DEBUG(3,("get_printerdrivernumber: Failed to lookup driver [%s]\n", 
+                       printer->info_2->drivername));
+               goto done;
        }
-
+       
+       /* count the number of files */
+       while ( driver.info_3->dependentfiles && *driver.info_3->dependentfiles[result] )
+                       result++;
+                       \
  done:
-
-       file_lines_free(lines);
-
+       if ( printer )
+               free_a_printer( &printer, 2 );
+               
+       if ( driver.info_3 )
+               free_a_printer_driver( driver, 3 );
+               
        return result;
 }
 
@@ -846,7 +764,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
        char *str2 = skip_string(str1,1);
        char *p = skip_string(str2,1);
        char *QueueName = p;
-       int uLevel;
+       unsigned int uLevel;
        int count=0;
        int snum;
        char* str3;
@@ -879,25 +797,17 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
                 */
                *rdata_len = 0;
                *rparam_len = 6;
-               *rparam = REALLOC(*rparam,*rparam_len);
+               *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
                SSVALS(*rparam,0,ERRunknownlevel);
                SSVAL(*rparam,2,0);
                SSVAL(*rparam,4,0);
                return(True);
        }
  
-       snum = lp_servicenumber(QueueName);
-       if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
-               int pnum = lp_servicenumber(PRINTERS_NAME);
-               if (pnum >= 0) {
-                       lp_add_printer(QueueName,pnum);
-                       snum = lp_servicenumber(QueueName);
-               }
-       }
-  
-       if (snum < 0 || !VALID_SNUM(snum))
-               return(False);
-
+       snum = find_service(QueueName);
+       if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
+               return False;
+               
        if (uLevel==52) {
                count = get_printerdrivernumber(snum);
                DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
@@ -906,7 +816,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
        }
 
        if (mdrcnt > 0) {
-               *rdata = REALLOC(*rdata,mdrcnt);
+               *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
                desc.base = *rdata;
                desc.buflen = mdrcnt;
        } else {
@@ -915,7 +825,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
                 * init_package will return wrong size if buflen=0
                 */
                desc.buflen = getlen(desc.format);
-               desc.base = tmpdata = (char *) malloc (desc.buflen);
+               desc.base = tmpdata = (char *) SMB_MALLOC (desc.buflen);
        }
 
        if (init_package(&desc,1,count)) {
@@ -935,7 +845,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
  
        *rdata_len = desc.usedlen;
        *rparam_len = 6;
-       *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
        SSVALS(*rparam,0,desc.errcode);
        SSVAL(*rparam,2,0);
        SSVAL(*rparam,4,desc.neededlen);
@@ -957,137 +867,172 @@ static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param,
                              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);
-  int uLevel = SVAL(p,0);
-  char *output_format2 = p + 4;
-  int services = lp_numservices();
-  int i, n;
-  struct pack_desc desc;
-  print_queue_struct **queue = NULL;
-  print_status_struct *status = NULL;
-  int* subcntarr = NULL;
-  int queuecnt, subcnt=0, succnt=0;
+       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;
+       int services = lp_numservices();
+       int i, n;
+       struct pack_desc desc;
+       print_queue_struct **queue = NULL;
+       print_status_struct *status = NULL;
+       int *subcntarr = NULL;
+       int queuecnt = 0, subcnt = 0, succnt = 0;
  
-  memset((char *)&desc,'\0',sizeof(desc));
+       memset((char *)&desc,'\0',sizeof(desc));
 
-  DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
+       DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
  
-  if (!prefix_ok(param_format,"WrLeh")) return False;
-  if (!check_printq_info(&desc,uLevel,output_format1,output_format2)) {
-    /*
-     * Patch from Scott Moomaw <scott@bridgewater.edu>
-     * to return the 'invalid info level' error if an
-     * unknown level was requested.
-     */
-    *rdata_len = 0;
-    *rparam_len = 6;
-    *rparam = REALLOC(*rparam,*rparam_len);
-    SSVALS(*rparam,0,ERRunknownlevel);
-    SSVAL(*rparam,2,0);
-    SSVAL(*rparam,4,0);
-    return(True);
-  }
+       if (!prefix_ok(param_format,"WrLeh")) {
+               return False;
+       }
+       if (!check_printq_info(&desc,uLevel,output_format1,output_format2)) {
+               /*
+                * Patch from Scott Moomaw <scott@bridgewater.edu>
+                * to return the 'invalid info level' error if an
+                * unknown level was requested.
+                */
+               *rdata_len = 0;
+               *rparam_len = 6;
+               *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+               SSVALS(*rparam,0,ERRunknownlevel);
+               SSVAL(*rparam,2,0);
+               SSVAL(*rparam,4,0);
+               return(True);
+       }
 
-  queuecnt = 0;
-  for (i = 0; i < services; i++)
-    if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
-      queuecnt++;
-  if (uLevel > 0) {
-    if((queue = (print_queue_struct**)malloc(queuecnt*sizeof(print_queue_struct*))) == NULL) {
-      DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
-      return False;
-    }
-    memset(queue,0,queuecnt*sizeof(print_queue_struct*));
-    if((status = (print_status_struct*)malloc(queuecnt*sizeof(print_status_struct))) == NULL) {
-      DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
-      return False;
-    }
-    memset(status,0,queuecnt*sizeof(print_status_struct));
-    if((subcntarr = (int*)malloc(queuecnt*sizeof(int))) == NULL) {
-      DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
-      return False;
-    }
-    subcnt = 0;
-    n = 0;
-    for (i = 0; i < services; i++)
-      if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
-       subcntarr[n] = print_queue_status(i, &queue[n],&status[n]);
-       subcnt += subcntarr[n];
-       n++;
-      }
-  }
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  desc.base = *rdata;
-  desc.buflen = mdrcnt;
+       for (i = 0; i < services; i++) {
+               if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
+                       queuecnt++;
+               }
+       }
 
-  if (init_package(&desc,queuecnt,subcnt)) {
-    n = 0;
-    succnt = 0;
-    for (i = 0; i < services; i++)
-      if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
-       fill_printq_info(conn,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
-       n++;
-       if (desc.errcode == NERR_Success) succnt = n;
-      }
-  }
+       if((queue = SMB_MALLOC_ARRAY(print_queue_struct*, queuecnt)) == NULL) {
+               DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+               goto err;
+       }
+       memset(queue,0,queuecnt*sizeof(print_queue_struct*));
+       if((status = SMB_MALLOC_ARRAY(print_status_struct,queuecnt)) == NULL) {
+               DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+               goto err;
+       }
+       memset(status,0,queuecnt*sizeof(print_status_struct));
+       if((subcntarr = SMB_MALLOC_ARRAY(int,queuecnt)) == NULL) {
+               DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+               goto err;
+       }
+
+       subcnt = 0;
+       n = 0;
+       for (i = 0; i < services; i++) {
+               if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
+                       subcntarr[n] = print_queue_status(i, &queue[n],&status[n]);
+                       subcnt += subcntarr[n];
+                       n++;
+               }
+       }
+
+       if (mdrcnt > 0) {
+               *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
+               if (!*rdata) {
+                       goto err;
+               }
+       }
+       desc.base = *rdata;
+       desc.buflen = mdrcnt;
+
+       if (init_package(&desc,queuecnt,subcnt)) {
+               n = 0;
+               succnt = 0;
+               for (i = 0; i < services; i++) {
+                       if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
+                               fill_printq_info(conn,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
+                               n++;
+                               if (desc.errcode == NERR_Success) {
+                                       succnt = n;
+                               }
+                       }
+               }
+       }
 
-  SAFE_FREE(subcntarr);
+       SAFE_FREE(subcntarr);
  
-  *rdata_len = desc.usedlen;
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,succnt);
-  SSVAL(*rparam,6,queuecnt);
+       *rdata_len = desc.usedlen;
+       *rparam_len = 8;
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+       if (!*rparam) {
+               goto err;
+       }
+       SSVALS(*rparam,0,desc.errcode);
+       SSVAL(*rparam,2,0);
+       SSVAL(*rparam,4,succnt);
+       SSVAL(*rparam,6,queuecnt);
   
-  for (i = 0; i < queuecnt; i++) {
-    if (queue) SAFE_FREE(queue[i]);
-  }
+       for (i = 0; i < queuecnt; i++) {
+               if (queue) {
+                       SAFE_FREE(queue[i]);
+               }
+       }
 
-  SAFE_FREE(queue);
-  SAFE_FREE(status);
+       SAFE_FREE(queue);
+       SAFE_FREE(status);
   
-  return True;
+       return True;
+
+  err:
+
+       SAFE_FREE(subcntarr);
+       for (i = 0; i < queuecnt; i++) {
+               if (queue) {
+                       SAFE_FREE(queue[i]);
+               }
+       }
+       SAFE_FREE(queue);
+       SAFE_FREE(status);
+
+       return False;
 }
 
 /****************************************************************************
-  get info level for a server list query
-  ****************************************************************************/
+ Get info level for a server list query.
+****************************************************************************/
+
 static BOOL check_server_info(int uLevel, char* id)
 {
-  switch( uLevel ) {
-  case 0:
-    if (strcmp(id,"B16") != 0) return False;
-    break;
-  case 1:
-    if (strcmp(id,"B16BBDz") != 0) return False;
-    break;
-  default: 
-    return False;
-  }
-  return True;
+       switch( uLevel ) {
+               case 0:
+                       if (strcmp(id,"B16") != 0) {
+                               return False;
+                       }
+                       break;
+               case 1:
+                       if (strcmp(id,"B16BBDz") != 0) {
+                               return False;
+                       }
+                       break;
+               default: 
+                       return False;
+       }
+       return True;
 }
 
-struct srv_info_struct
-{
-  fstring name;
-  uint32 type;
-  fstring comment;
-  fstring domain;
-  BOOL server_added;
+struct srv_info_struct {
+       fstring name;
+       uint32 type;
+       fstring comment;
+       fstring domain;
+       BOOL server_added;
 };
 
-
 /*******************************************************************
-  get server info lists from the files saved by nmbd. Return the
-  number of entries
-  ******************************************************************/
+ Get server info lists from the files saved by nmbd. Return the
+ number of entries.
+******************************************************************/
+
 static int get_server_info(uint32 servertype, 
                           struct srv_info_struct **servers,
-                          char *domain)
+                          const char *domain)
 {
   int count=0;
   int alloced=0;
@@ -1112,7 +1057,7 @@ static int get_server_info(uint32 servertype,
   for (i=0;lines[i];i++) {
     fstring stype;
     struct srv_info_struct *s;
-    char *ptr = lines[i];
+    const char *ptr = lines[i];
     BOOL ok = True;
 
     if (!*ptr) continue;
@@ -1121,8 +1066,7 @@ static int get_server_info(uint32 servertype,
       struct srv_info_struct *ts;
       
       alloced += 10;
-      ts = (struct srv_info_struct *)
-       Realloc(*servers,sizeof(**servers)*alloced);
+      ts = SMB_REALLOC_ARRAY(*servers,struct srv_info_struct, alloced);
       if (!ts) {
        DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
        return(0);
@@ -1137,7 +1081,7 @@ static int get_server_info(uint32 servertype,
     if (!next_token(&ptr,s->comment, NULL, sizeof(s->comment))) continue;
     if (!next_token(&ptr,s->domain , NULL, sizeof(s->domain))) {
       /* this allows us to cope with an old nmbd */
-      pstrcpy(s->domain,global_myworkgroup); 
+      fstrcpy(s->domain,lp_workgroup()); 
     }
     
     if (sscanf(stype,"%X",&s->type) != 1) { 
@@ -1193,10 +1137,10 @@ static int get_server_info(uint32 servertype,
   return(count);
 }
 
-
 /*******************************************************************
-  fill in a server info structure
-  ******************************************************************/
+ Fill in a server info structure.
+******************************************************************/
+
 static int fill_srv_info(struct srv_info_struct *service, 
                         int uLevel, char **buf, int *buflen, 
                         char **stringbuf, int *stringspace, char *baseaddr)
@@ -1246,11 +1190,11 @@ static int fill_srv_info(struct srv_info_struct *service,
   switch (uLevel)
     {
     case 0:
-           push_ascii(p,service->name, 15, STR_TERMINATE);
+           push_ascii(p,service->name, MAX_NETBIOSNAME_LEN, STR_TERMINATE);
            break;
 
     case 1:
-           push_ascii(p,service->name,15, STR_TERMINATE);
+           push_ascii(p,service->name,MAX_NETBIOSNAME_LEN, STR_TERMINATE);
            SIVAL(p,18,service->type);
            SIVAL(p,22,PTR_DIFF(p2,baseaddr));
            len += CopyAndAdvance(&p2,service->comment,&l2);
@@ -1275,13 +1219,14 @@ static int fill_srv_info(struct srv_info_struct *service,
 
 static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
 {
-  return(strcmp(s1->name,s2->name));
+       return(strcmp(s1->name,s2->name));
 }
 
 /****************************************************************************
-  view list of servers available (or possibly domains). The info is
-  extracted from lists saved by nmbd on the local host
-  ****************************************************************************/
+ View list of servers available (or possibly domains). The info is
+ 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)
@@ -1333,7 +1278,7 @@ static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param
   if (strcmp(str1, "WrLehDz") == 0) {
          pull_ascii_fstring(domain, p);
   } else {
-         fstrcpy(domain, global_myworkgroup);
+         fstrcpy(domain, lp_workgroup());
   }
 
   if (lp_browse_list())
@@ -1368,7 +1313,7 @@ static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param
   }
 
   *rdata_len = fixed_len + string_len;
-  *rdata = REALLOC(*rdata,*rdata_len);
+  *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
   memset(*rdata,'\0',*rdata_len);
   
   p2 = (*rdata) + fixed_len;   /* auxilliary data (strings) will go here */
@@ -1392,7 +1337,7 @@ static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param
   }
   
   *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERRmoredata));
   SSVAL(*rparam,2,0);
   SSVAL(*rparam,4,counted);
@@ -1409,6 +1354,7 @@ 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)
@@ -1429,7 +1375,7 @@ static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid, char *pa
   *rdata_len = 0;
   
   *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
 
   SSVAL(*rparam,0,0x08AC); /* informational warning message */
   SSVAL(*rparam,2,0);
@@ -1442,6 +1388,7 @@ static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid, char *pa
 /****************************************************************************
   get info about a share
   ****************************************************************************/
+
 static BOOL check_share_info(int uLevel, char* id)
 {
   switch( uLevel ) {
@@ -1575,13 +1522,13 @@ static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *para
   if (!prefix_ok(str1,"zWrLh")) return False;
   if (!check_share_info(uLevel,str2)) return False;
  
-  *rdata = REALLOC(*rdata,mdrcnt);
+  *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
   p = *rdata;
   *rdata_len = fill_share_info(conn,snum,uLevel,&p,&mdrcnt,0,0,0);
   if (*rdata_len < 0) return False;
  
   *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVAL(*rparam,0,NERR_Success);
   SSVAL(*rparam,2,0);          /* converter word */
   SSVAL(*rparam,4,*rdata_len);
@@ -1590,12 +1537,25 @@ static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *para
 }
 
 /****************************************************************************
-  view list of shares available
-  ****************************************************************************/
-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)
+  View the list of available shares.
+
+  This function is the server side of the NetShareEnum() RAP call.
+  It fills the return buffer with share names and share comments.
+  Note that the return buffer normally (in all known cases) allows only
+  twelve byte strings for share names (plus one for a nul terminator).
+  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 )
 {
   char *str1 = param+2;
   char *str2 = skip_string(str1,1);
@@ -1614,8 +1574,14 @@ static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,c
   if (!check_share_info(uLevel,str2)) return False;
   
   data_len = fixed_len = string_len = 0;
-  for (i=0;i<count;i++)
-    if (lp_browseable(i) && lp_snum_ok(i))
+  for (i=0;i<count;i++) {
+    fstring servicename_dos;
+    if (!(lp_browseable(i) && lp_snum_ok(i)))
+           continue;
+    push_ascii_fstring(servicename_dos, lp_servicename(i));
+    if( lp_browseable( i )
+        && lp_snum_ok( i )
+        && (strlen(servicename_dos) < 13) )   /* Maximum name length. */
     {
       total++;
       data_len += fill_share_info(conn,i,uLevel,0,&f_len,0,&s_len,0);
@@ -1628,21 +1594,32 @@ static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,c
       else
         missed = True;
     }
+  }
   *rdata_len = fixed_len + string_len;
-  *rdata = REALLOC(*rdata,*rdata_len);
+  *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
   memset(*rdata,0,*rdata_len);
   
   p2 = (*rdata) + fixed_len;   /* auxiliary data (strings) will go here */
   p = *rdata;
   f_len = fixed_len;
   s_len = string_len;
-  for (i = 0; i < count;i++)
-    if (lp_browseable(i) && lp_snum_ok(i))
-      if (fill_share_info(conn,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
+  for( i = 0; i < count; i++ )
+    {
+    fstring servicename_dos;
+    if (!(lp_browseable(i) && lp_snum_ok(i)))
+           continue;
+    push_ascii_fstring(servicename_dos, lp_servicename(i));
+    if( lp_browseable( i )
+        && lp_snum_ok( i )
+        && (strlen(servicename_dos) < 13) )
+      {
+      if( fill_share_info( conn,i,uLevel,&p,&f_len,&p2,&s_len,*rdata ) < 0 )
        break;
+      }
+    }
   
   *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVAL(*rparam,0,missed ? ERRmoredata : NERR_Success);
   SSVAL(*rparam,2,0);
   SSVAL(*rparam,4,counted);
@@ -1657,6 +1634,7 @@ static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,c
 /****************************************************************************
   Add a share
   ****************************************************************************/
+
 static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,char *data,
                                 int mdrcnt,int mprcnt,
                                 char **rdata,char **rparam,
@@ -1728,7 +1706,7 @@ static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,ch
   } else return False;
 
   *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVAL(*rparam,0,NERR_Success);
   SSVAL(*rparam,2,0);          /* converter word */
   SSVAL(*rparam,4,*rdata_len);
@@ -1738,17 +1716,17 @@ static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,ch
 
  error_exit:
   *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   *rdata_len = 0;
   SSVAL(*rparam,0,res);
   SSVAL(*rparam,2,0);
   return True;
-
 }
 
 /****************************************************************************
   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,
@@ -1761,7 +1739,9 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
        char *str2 = skip_string(str1,1);
        char *p = skip_string(str2,1);
 
-       GROUP_MAP *group_list;
+       struct pdb_search *search;
+       struct samr_displayentry *entries;
+
        int num_entries;
  
        if (strcmp(str1,"WrLeh") != 0)
@@ -1778,27 +1758,40 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
                return False;
 
        /* get list of domain groups SID_DOMAIN_GRP=2 */
-       if(!enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False, False)) {
+       become_root();
+       search = pdb_search_groups();
+       unbecome_root();
+
+       if (search == NULL) {
                DEBUG(3,("api_RNetGroupEnum:failed to get group list"));
                return False;
        }
 
        resume_context = SVAL(p,0); 
        cli_buf_size=SVAL(p+2,0);
-       DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: %d\n", resume_context, cli_buf_size));
+       DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: "
+                 "%d\n", resume_context, cli_buf_size));
+
+       become_root();
+       num_entries = pdb_search_entries(search, resume_context, 0xffffffff,
+                                        &entries);
+       unbecome_root();
 
        *rdata_len = cli_buf_size;
-       *rdata = REALLOC(*rdata,*rdata_len);
+       *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
 
        p = *rdata;
 
-       for(i=resume_context; i<num_entries; i++) {     
-               char* name=group_list[i].nt_name;
+       for(i=0; i<num_entries; i++) {
+               fstring name;
+               fstrcpy(name, entries[i].account_name);
                if( ((PTR_DIFF(p,*rdata)+21) <= *rdata_len) ) {
                        /* truncate the name at 21 chars. */
                        memcpy(p, name, 21); 
                        DEBUG(10,("adding entry %d group %s\n", i, p));
-                       p += 21; 
+                       p += 21;
+                       p += 5; /* Both NT4 and W2k3SP1 do padding here.
+                                  No idea why... */
                } else {
                        /* set overflow error */
                        DEBUG(3,("overflow on entry %d group %s\n", i, name));
@@ -1807,22 +1800,25 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
                }
        }
 
+       pdb_search_destroy(search);
+
        *rdata_len = PTR_DIFF(p,*rdata);
 
        *rparam_len = 8;
-       *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
 
        SSVAL(*rparam, 0, errflags);
        SSVAL(*rparam, 2, 0);           /* converter word */
-       SSVAL(*rparam, 4, i-resume_context);    /* is this right?? */
-       SSVAL(*rparam, 6, num_entries); /* is this right?? */
+       SSVAL(*rparam, 4, i);   /* is this right?? */
+       SSVAL(*rparam, 6, resume_context+num_entries);  /* is this right?? */
 
        return(True);
 }
 
 /*******************************************************************
-  get groups that a user is a member of
-  ******************************************************************/
+ 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,
@@ -1833,61 +1829,114 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
        char *UserName = skip_string(str2,1);
        char *p = skip_string(UserName,1);
        int uLevel = SVAL(p,0);
-       char *p2;
+       const char *level_string;
        int count=0;
+       SAM_ACCOUNT *sampw = NULL;
+       BOOL ret = False;
+       DOM_SID *sids;
+       gid_t *gids;
+       size_t num_groups;
+       size_t i;
+       struct passwd *passwd;
+       NTSTATUS result;
 
        *rparam_len = 8;
-       *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   
        /* check it's a supported varient */
-       if (!strcmp(str1,"zWrLeh"))
+       
+       if ( strcmp(str1,"zWrLeh") != 0 )
                return False;
+               
        switch( uLevel ) {
                case 0:
-                       p2 = "B21";
+                       level_string = "B21";
                        break;
                default:
                        return False;
        }
 
-       if (strcmp(p2,str2) != 0)
+       if (strcmp(level_string,str2) != 0)
                return False;
 
        *rdata_len = mdrcnt + 1024;
-       *rdata = REALLOC(*rdata,*rdata_len);
+       *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
 
        SSVAL(*rparam,0,NERR_Success);
        SSVAL(*rparam,2,0);             /* converter word */
 
        p = *rdata;
 
-       /* XXXX we need a real SAM database some day */
-       pstrcpy(p,"Users"); p += 21; count++;
-       pstrcpy(p,"Domain Users"); p += 21; count++;
-       pstrcpy(p,"Guests"); p += 21; count++;
-       pstrcpy(p,"Domain Guests"); p += 21; count++;
+       /* Lookup the user information; This should only be one of 
+          our accounts (not remote domains) */
+
+       passwd = getpwnam_alloc(UserName);
 
+       if (passwd == NULL)
+               return False;
+          
+       pdb_init_sam( &sampw );
+       
+       become_root();                                  /* ROOT BLOCK */
+
+       if ( !pdb_getsampwnam(sampw, UserName) )
+               goto out;
+
+       sids = NULL;
+       num_groups = 0;
+
+       result = pdb_enum_group_memberships(pdb_get_username(sampw),
+                                           passwd->pw_gid,
+                                           &sids, &gids, &num_groups);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto out;
+
+       for (i=0; i<num_groups; i++) {
+
+               const char *grp_name;
+       
+               if ( lookup_sid(sampw->mem_ctx, &sids[i], NULL, &grp_name,
+                               NULL) ) {
+                       pstrcpy(p, grp_name);
+                       p += 21; 
+                       count++;
+               }
+       }
+
+       SAFE_FREE(sids);
+       
        *rdata_len = PTR_DIFF(p,*rdata);
 
        SSVAL(*rparam,4,count); /* is this right?? */
        SSVAL(*rparam,6,count); /* is this right?? */
 
-       return(True);
+       ret = True;
+
+out:
+       unbecome_root();                                /* END ROOT BLOCK */
+
+       pdb_free_sam( &sampw );
+       passwd_free(&passwd);
+
+       return ret;
 }
 
 /*******************************************************************
-  get all users 
-  ******************************************************************/
+ 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)
 {
-       SAM_ACCOUNT  *pwd=NULL;
        int count_sent=0;
-       int count_total=0;
+       int num_users=0;
        int errflags=0;
-       int resume_context, cli_buf_size;
+       int i, resume_context, cli_buf_size;
+       struct pdb_search *search;
+       struct samr_displayentry *users;
 
        char *str1 = param+2;
        char *str2 = skip_string(str1,1);
@@ -1905,72 +1954,70 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
   
        resume_context = SVAL(p,0);
        cli_buf_size=SVAL(p+2,0);
-       DEBUG(10,("api_RNetUserEnum:resume context: %d, client buffer size: %d\n", resume_context, cli_buf_size));
+       DEBUG(10,("api_RNetUserEnum:resume context: %d, client buffer size: %d\n",
+                       resume_context, cli_buf_size));
 
        *rparam_len = 8;
-       *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
 
        /* check it's a supported varient */
        if (strcmp("B21",str2) != 0)
                return False;
 
        *rdata_len = cli_buf_size;
-       *rdata = REALLOC(*rdata,*rdata_len);
+       *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
 
        p = *rdata;
 
-       /* to get user list enumerations for NetUserEnum in B21 format */
-       pdb_init_sam(&pwd);
-       
-       /* Open the passgrp file - not for update. */
        become_root();
-       if(!pdb_setsampwent(False)) {
+       search = pdb_search_users(ACB_NORMAL);
+       unbecome_root();
+       if (search == NULL) {
                DEBUG(0, ("api_RNetUserEnum:unable to open sam database.\n"));
-               unbecome_root();
                return False;
        }
-       errflags=NERR_Success;
-
-       while ( pdb_getsampwent(pwd) ) {
-               const char *name=pdb_get_username(pwd); 
-               if ((name) && (*(name+strlen(name)-1)!='$')) { 
-                       count_total++;
-                       if(count_total>=resume_context) {
-                               if( ((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21)  ) {
-                                       pstrcpy(p,name); 
-                                       DEBUG(10,("api_RNetUserEnum:adding entry %d username %s\n",count_sent,p));
-                                       p += 21; 
-                                       count_sent++; 
-                               } else {
-                                       /* set overflow error */
-                                       DEBUG(10,("api_RNetUserEnum:overflow on entry %d username %s\n",count_sent,name));
-                                       errflags=234;
-                                       break;
-                               }
-                       }
-               }       
-       } ;
 
-       pdb_endsampwent();
+       become_root();
+       num_users = pdb_search_entries(search, resume_context, 0xffffffff,
+                                      &users);
        unbecome_root();
 
-       pdb_free_sam(&pwd);
+       errflags=NERR_Success;
+
+       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); 
+                       DEBUG(10,("api_RNetUserEnum:adding entry %d username "
+                                 "%s\n",count_sent,p));
+                       p += 21; 
+                       count_sent++; 
+               } else {
+                       /* set overflow error */
+                       DEBUG(10,("api_RNetUserEnum:overflow on entry %d "
+                                 "username %s\n",count_sent,name));
+                       errflags=234;
+                       break;
+               }
+       }
+
+       pdb_search_destroy(search);
 
        *rdata_len = PTR_DIFF(p,*rdata);
 
        SSVAL(*rparam,0,errflags);
        SSVAL(*rparam,2,0);           /* converter word */
        SSVAL(*rparam,4,count_sent);  /* is this right?? */
-       SSVAL(*rparam,6,count_total); /* is this right?? */
+       SSVAL(*rparam,6,num_users); /* is this right?? */
 
        return True;
 }
 
-
-
 /****************************************************************************
-  get the time of day info
-  ****************************************************************************/
+ 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,
@@ -1978,10 +2025,10 @@ static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,ch
 {
   char *p;
   *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
 
   *rdata_len = 21;
-  *rdata = REALLOC(*rdata,*rdata_len);
+  *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
 
   SSVAL(*rparam,0,NERR_Success);
   SSVAL(*rparam,2,0);          /* converter word */
@@ -1992,28 +2039,26 @@ static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,ch
     struct tm *t;
     time_t unixdate = time(NULL);
 
-    put_dos_date3(p,0,unixdate); /* this is the time that is looked at
+    srv_put_dos_date3(p,0,unixdate); /* this is the time that is looked at
                                    by NT in a "net time" operation,
                                    it seems to ignore the one below */
 
     /* the client expects to get localtime, not GMT, in this bit 
        (I think, this needs testing) */
-    t = LocalTime(&unixdate);
+    t = localtime(&unixdate);
 
     SIVAL(p,4,0);              /* msecs ? */
     SCVAL(p,8,t->tm_hour);
     SCVAL(p,9,t->tm_min);
     SCVAL(p,10,t->tm_sec);
     SCVAL(p,11,0);             /* hundredths of seconds */
-    SSVALS(p,12,TimeDiff(unixdate)/60); /* timezone in minutes from GMT */
+    SSVALS(p,12,get_time_zone(unixdate)/60); /* timezone in minutes from GMT */
     SSVAL(p,14,10000);         /* timer interval in 0.0001 of sec */
     SCVAL(p,16,t->tm_mday);
     SCVAL(p,17,t->tm_mon + 1);
     SSVAL(p,18,1900+t->tm_year);
     SCVAL(p,20,t->tm_wday);
   }
-
-
   return(True);
 }
 
@@ -2026,94 +2071,78 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
                                char **rdata,char **rparam,
                                int *rdata_len,int *rparam_len)
 {
-  char *p = skip_string(param+2,2);
-  fstring user;
-  fstring pass1,pass2;
+       char *p = skip_string(param+2,2);
+       fstring user;
+       fstring pass1,pass2;
 
-  pull_ascii_fstring(user,p);
+       pull_ascii_fstring(user,p);
 
-  p = skip_string(p,1);
+       p = skip_string(p,1);
 
-  memset(pass1,'\0',sizeof(pass1));
-  memset(pass2,'\0',sizeof(pass2));
-  memcpy(pass1,p,16);
-  memcpy(pass2,p+16,16);
+       memset(pass1,'\0',sizeof(pass1));
+       memset(pass2,'\0',sizeof(pass2));
+       memcpy(pass1,p,16);
+       memcpy(pass2,p+16,16);
 
-  *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam_len = 4;
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
 
-  *rdata_len = 0;
+       *rdata_len = 0;
 
-  SSVAL(*rparam,0,NERR_badpass);
-  SSVAL(*rparam,2,0);          /* converter word */
+       SSVAL(*rparam,0,NERR_badpass);
+       SSVAL(*rparam,2,0);             /* converter word */
 
-  DEBUG(3,("Set password for <%s>\n",user));
+       DEBUG(3,("Set password for <%s>\n",user));
 
-  /*
-   * Attempt to verify the old password against smbpasswd entries
-   * Win98 clients send old and new password in plaintext for this call.
-   */
+       /*
+        * Attempt to verify the old password against smbpasswd entries
+        * Win98 clients send old and new password in plaintext for this call.
+        */
 
-  {
-         auth_serversupplied_info *server_info = NULL;
-         DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
-         if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
-
-                 /*
-                  * If unix password sync was requested, attempt to change
-                  * the /etc/passwd database first. Return failure if this cannot
-                  * be done.
-                  *
-                  * This occurs before the oem change, becouse we don't want to
-                   * update it if chgpasswd failed.
-                  *
-                  * Conditional on lp_unix_password_sync() becouse we don't want
-                   * to touch the unix db unless we have admin permission.
-                  */
-                 
-                 if(lp_unix_password_sync() && IS_SAM_UNIX_USER(server_info->sam_account) 
-                    && !chgpasswd(pdb_get_username(server_info->sam_account),
-                                  pass1,pass2,False)) {
-                         SSVAL(*rparam,0,NERR_badpass);
-                 }
-                 
-                 if (change_oem_password(server_info->sam_account,pass2))
-                 {
-                         SSVAL(*rparam,0,NERR_Success);
-                 }
-                 
-                 free_server_info(&server_info);
-         }
-         data_blob_clear_free(&password);
-  }
+       {
+               auth_serversupplied_info *server_info = NULL;
+               DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
 
-  /*
-   * If the plaintext change failed, attempt
-   * the old encrypted method. NT will generate this
-   * after trying the samr method. Note that this
-   * method is done as a last resort as this
-   * password change method loses the NT password hash
-   * and cannot change the UNIX password as no plaintext
-   * is received.
-   */
+               if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
 
-  if(SVAL(*rparam,0) != NERR_Success)
-  {
-    SAM_ACCOUNT *hnd = NULL;
+                       become_root();
+                       if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2, False))) {
+                               SSVAL(*rparam,0,NERR_Success);
+                       }
+                       unbecome_root();
 
-    if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd) && 
-       change_lanman_password(hnd,(unsigned char *)pass1,(unsigned char *)pass2))
-    {
-      SSVAL(*rparam,0,NERR_Success);
-    }
-       pdb_free_sam(&hnd);
-  }
+                       free_server_info(&server_info);
+               }
+               data_blob_clear_free(&password);
+       }
+
+       /*
+        * If the plaintext change failed, attempt
+        * the old encrypted method. NT will generate this
+        * after trying the samr method. Note that this
+        * method is done as a last resort as this
+        * password change method loses the NT password hash
+        * and cannot change the UNIX password as no plaintext
+        * is received.
+        */
+
+       if(SVAL(*rparam,0) != NERR_Success) {
+               SAM_ACCOUNT *hnd = NULL;
 
+               if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd)) {
+                       become_root();
+                       if (change_lanman_password(hnd,(uchar *)pass2)) {
+                               SSVAL(*rparam,0,NERR_Success);
+                       }
+                       unbecome_root();
+                       pdb_free_sam(&hnd);
+               }
+       }
 
-  memset((char *)pass1,'\0',sizeof(fstring));
-  memset((char *)pass2,'\0',sizeof(fstring));   
+       memset((char *)pass1,'\0',sizeof(fstring));
+       memset((char *)pass2,'\0',sizeof(fstring));      
         
-  return(True);
+       return(True);
 }
 
 /****************************************************************************
@@ -2125,53 +2154,53 @@ static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *
                                char **rdata,char **rparam,
                                int *rdata_len,int *rparam_len)
 {
-  fstring user;
-  char *p = param + 2;
-  *rparam_len = 2;
-  *rparam = REALLOC(*rparam,*rparam_len);
+       fstring user;
+       char *p = param + 2;
+       *rparam_len = 2;
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
 
-  *rdata_len = 0;
+       *rdata_len = 0;
 
-  SSVAL(*rparam,0,NERR_badpass);
+       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));
-    return False;
-  }
-  p = skip_string(p, 1);
+       /*
+        * Check the parameter definition is correct.
+        */
 
-  if(!strequal(p, "B516B16")) {
-    DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
-    return False;
-  }
-  p = skip_string(p,1);
+       if(!strequal(param + 2, "zsT")) {
+               DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
+               return False;
+       }
+       p = skip_string(p, 1);
 
-  p += pull_ascii_fstring(user,p);
+       if(!strequal(p, "B516B16")) {
+               DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
+               return False;
+       }
+       p = skip_string(p,1);
+       p += pull_ascii_fstring(user,p);
 
-  DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
+       DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
 
-  /*
-   * Pass the user through the NT -> unix user mapping
-   * function.
-   */
+       /*
+        * Pass the user through the NT -> unix user mapping
+        * function.
+        */
 
-  (void)map_username(user);
+       (void)map_username(user);
 
-  if (pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL))
-  {
-    SSVAL(*rparam,0,NERR_Success);
-  }
+       if (NT_STATUS_IS_OK(pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL))) {
+               SSVAL(*rparam,0,NERR_Success);
+       }
 
-  return(True);
+       return(True);
 }
 
 /****************************************************************************
   delete a print job
   Form: <W> <> 
   ****************************************************************************/
+
 static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param,char *data,
                                int mdrcnt,int mprcnt,
                                char **rdata,char **rparam,
@@ -2181,38 +2210,47 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
        char *str1 = param+2;
        char *str2 = skip_string(str1,1);
        char *p = skip_string(str2,1);
-       int jobid, errcode;
-       extern struct current_user current_user;
+       uint32 jobid;
+       int snum;
+       fstring sharename;
+       int errcode;
        WERROR werr = WERR_OK;
 
-       jobid = rap_to_pjobid(SVAL(p,0));
+       if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
+               return False;
 
        /* check it's a supported varient */
        if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
                return(False);
 
        *rparam_len = 4;
-       *rparam = REALLOC(*rparam,*rparam_len); 
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);       
        *rdata_len = 0;
 
-       if (!print_job_exists(jobid)) {
+       if (!print_job_exists(sharename, jobid)) {
                errcode = NERR_JobNotFound;
                goto out;
        }
 
+       snum = lp_servicenumber( sharename);
+       if (snum == -1) {
+               errcode = NERR_DestNotFound;
+               goto out;
+       }
+
        errcode = NERR_notsupported;
        
        switch (function) {
        case 81:                /* delete */ 
-               if (print_job_delete(&current_user, jobid, &werr)) 
+               if (print_job_delete(&current_user, snum, jobid, &werr)) 
                        errcode = NERR_Success;
                break;
        case 82:                /* pause */
-               if (print_job_pause(&current_user, jobid, &werr)) 
+               if (print_job_pause(&current_user, snum, jobid, &werr)) 
                        errcode = NERR_Success;
                break;
        case 83:                /* resume */
-               if (print_job_resume(&current_user, jobid, &werr)) 
+               if (print_job_resume(&current_user, snum, jobid, &werr)) 
                        errcode = NERR_Success;
                break;
        }
@@ -2230,6 +2268,7 @@ 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,
@@ -2242,14 +2281,13 @@ static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid, char *param
        int errcode = NERR_notsupported;
        int snum;
        WERROR werr = WERR_OK;
-       extern struct current_user current_user;
 
        /* check it's a supported varient */
        if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
                return(False);
 
        *rparam_len = 4;
-       *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
        *rdata_len = 0;
 
        snum = print_queue_snum(QueueName);
@@ -2280,7 +2318,6 @@ static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid, char *param
        return(True);
 }
 
-
 /****************************************************************************
   set the property of a print job (undocumented?)
   ? function = 0xb -> set name of print job
@@ -2288,6 +2325,7 @@ static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid, char *param
   Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz> 
   or   <WWsTP> <WB21BB16B10zWWzDDz> 
 ****************************************************************************/
+
 static int check_printjob_info(struct pack_desc* desc,
                               int uLevel, char* id)
 {
@@ -2313,14 +2351,23 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
        char *str1 = param+2;
        char *str2 = skip_string(str1,1);
        char *p = skip_string(str2,1);
-       int jobid;
+       uint32 jobid;
+       int snum;
+       fstring sharename;
        int uLevel = SVAL(p,2);
        int function = SVAL(p,4);
        int place, errcode;
 
-       jobid = rap_to_pjobid(SVAL(p,0));
+       if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
+               return False;
        *rparam_len = 4;
-       *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
+
+       if ( (snum = lp_servicenumber(sharename)) == -1 ) {
+               DEBUG(0,("api_PrintJobInfo: unable to get service number from sharename [%s]\n",
+                       sharename));
+               return False;
+       }
   
        *rdata_len = 0;
        
@@ -2329,7 +2376,7 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
            (!check_printjob_info(&desc,uLevel,str2)))
                return(False);
 
-       if (!print_job_exists(jobid)) {
+       if (!print_job_exists(sharename, jobid)) {
                errcode=NERR_JobNotFound;
                goto out;
        }
@@ -2341,14 +2388,14 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
                /* change job place in the queue, 
                   data gives the new place */
                place = SVAL(data,0);
-               if (print_job_set_place(jobid, place)) {
+               if (print_job_set_place(snum, jobid, place)) {
                        errcode=NERR_Success;
                }
                break;
 
        case 0xb:   
                /* change print job name, data gives the name */
-               if (print_job_set_name(jobid, data)) {
+               if (print_job_set_name(snum, jobid, data)) {
                        errcode=NERR_Success;
                }
                break;
@@ -2366,8 +2413,9 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
 
 
 /****************************************************************************
-  get info about the server
-  ****************************************************************************/
+ 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,
@@ -2415,12 +2463,12 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
   }
 
   *rdata_len = mdrcnt;
-  *rdata = REALLOC(*rdata,*rdata_len);
+  *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
 
   p = *rdata;
   p2 = p + struct_len;
   if (uLevel != 20) {
-    srvstr_push(NULL, p,local_machine,16, 
+    srvstr_push(NULL, p,get_local_machine_name(),16, 
                STR_ASCII|STR_UPPER|STR_TERMINATE);
   }
   p += 16;
@@ -2431,15 +2479,15 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
       pstring comment;
       uint32 servertype= lp_default_server_announce();
 
-      pstrcpy(comment,string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
+      push_ascii(comment,lp_serverstring(), MAX_SERVER_STRING_LENGTH,STR_TERMINATE);
 
-      if ((count=get_server_info(SV_TYPE_ALL,&servers,global_myworkgroup))>0) {
-       for (i=0;i<count;i++)
-         if (strequal(servers[i].name,local_machine))
-      {
+      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())) {
            servertype = servers[i].type;
-           pstrcpy(comment,servers[i].comment);            
+           push_ascii(comment,servers[i].comment,sizeof(pstring),STR_TERMINATE);           
          }
+       }
       }
       SAFE_FREE(servers);
 
@@ -2464,7 +2512,7 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
   *rdata_len = PTR_DIFF(p2,*rdata);
 
   *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVAL(*rparam,0,NERR_Success);
   SSVAL(*rparam,2,0);          /* converter word */
   SSVAL(*rparam,4,*rdata_len);
@@ -2472,10 +2520,10 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
   return(True);
 }
 
-
 /****************************************************************************
-  get info about the server
-  ****************************************************************************/
+ Get info about the server.
+****************************************************************************/
+
 static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
                                int mdrcnt,int mprcnt,
                                char **rdata,char **rparam,
@@ -2485,20 +2533,19 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
   char *str2 = skip_string(str1,1);
   char *p = skip_string(str2,1);
   char *p2;
-  extern userdom_struct current_user_info;
   int level = SVAL(p,0);
 
   DEBUG(4,("NetWkstaGetInfo level %d\n",level));
 
   *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
 
   /* check it's a supported varient */
   if (!(level==10 && strcsequal(str1,"WrLh") && strcsequal(str2,"zzzBBzz")))
     return(False);
 
   *rdata_len = mdrcnt + 1024;
-  *rdata = REALLOC(*rdata,*rdata_len);
+  *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
 
   SSVAL(*rparam,0,NERR_Success);
   SSVAL(*rparam,2,0);          /* converter word */
@@ -2508,8 +2555,8 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
 
 
   SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* host name */
-  pstrcpy(p2,local_machine);
-  strupper(p2);
+  pstrcpy(p2,get_local_machine_name());
+  strupper_m(p2);
   p2 = skip_string(p2,1);
   p += 4;
 
@@ -2519,8 +2566,8 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
   p += 4;
 
   SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
-  pstrcpy(p2,global_myworkgroup);
-  strupper(p2);
+  pstrcpy(p2,lp_workgroup());
+  strupper_m(p2);
   p2 = skip_string(p2,1);
   p += 4;
 
@@ -2529,7 +2576,7 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
   p += 2;
 
   SIVAL(p,0,PTR_DIFF(p2,*rdata));
-  pstrcpy(p2,global_myworkgroup);      /* don't know.  login domain?? */
+  pstrcpy(p2,lp_workgroup());  /* don't know.  login domain?? */
   p2 = skip_string(p2,1);
   p += 4;
 
@@ -2726,36 +2773,41 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
        char *p = skip_string(UserName,1);
        int uLevel = SVAL(p,0);
        char *p2;
+       const char *level_string;
+
+       /* get NIS home of a previously validated user - simeon */
+       /* With share level security vuid will always be zero.
+          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));
+       }
 
-    /* get NIS home of a previously validated user - simeon */
-    /* With share level security vuid will always be zero.
-       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));
-
-    *rparam_len = 6;
-    *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam_len = 6;
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
 
-    DEBUG(4,("RNetUserGetInfo level=%d\n", uLevel));
+       DEBUG(4,("RNetUserGetInfo level=%d\n", uLevel));
   
        /* check it's a supported variant */
-       if (strcmp(str1,"zWrLh") != 0) return False;
-       switch( uLevel )
-       {
-               case 0: p2 = "B21"; break;
-               case 1: p2 = "B21BB16DWzzWz"; break;
-               case 2: p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
-               case 10: p2 = "B21Bzzz"; break;
-               case 11: p2 = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
+       if (strcmp(str1,"zWrLh") != 0) {
+               return False;
+       }
+       switch( uLevel ) {
+               case 0: level_string = "B21"; break;
+               case 1: level_string = "B21BB16DWzzWz"; break;
+               case 2: level_string = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
+               case 10: level_string = "B21Bzzz"; break;
+               case 11: level_string = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
                default: return False;
        }
 
-       if (strcmp(p2,str2) != 0) return False;
+       if (strcmp(level_string,str2) != 0) {
+               return False;
+       }
 
        *rdata_len = mdrcnt + 1024;
-       *rdata = REALLOC(*rdata,*rdata_len);
+       *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
 
        SSVAL(*rparam,0,NERR_Success);
        SSVAL(*rparam,2,0);             /* converter word */
@@ -2766,13 +2818,12 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
        memset(p,0,21); 
        fstrcpy(p+usri11_name,UserName); /* 21 bytes - user name */
 
-       if (uLevel > 0)
-       {
+       if (uLevel > 0) {
                SCVAL(p,usri11_pad,0); /* padding - 1 byte */
                *p2 = 0;
        }
-       if (uLevel >= 10)
-       {
+
+       if (uLevel >= 10) {
                SIVAL(p,usri11_comment,PTR_DIFF(p2,p)); /* comment */
                pstrcpy(p2,"Comment");
                p2 = skip_string(p2,1);
@@ -2787,8 +2838,8 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
                p2 = skip_string(p2,1);
        }
 
-       if (uLevel == 11) /* modelled after NTAS 3.51 reply */
-       {         
+       if (uLevel == 11) {
+               /* 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 */
@@ -2822,8 +2873,8 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
 
                SSVAL(p,usri11_code_page,0);            /* code page */
        }
-       if (uLevel == 1 || uLevel == 2)
-       {
+
+       if (uLevel == 1 || uLevel == 2) {
                memset(p+22,' ',16);    /* password */
                SIVALS(p,38,-1);                /* password age */
                SSVAL(p,42,
@@ -2837,8 +2888,7 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
                SIVAL(p,54,PTR_DIFF(p2,*rdata));                /* script_path */
                pstrcpy(p2,vuser && vuser->logon_script ? vuser->logon_script : "");
                p2 = skip_string(p2,1);
-               if (uLevel == 2)
-               {
+               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));
@@ -2902,7 +2952,7 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
   /* check it's a supported varient */
   if (strcmp(str1,"OOWb54WrLh") != 0) return False;
   if (uLevel != 1 || strcmp(str2,"WB21BWDWWDDDDDDDzzzD") != 0) return False;
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+  if (mdrcnt > 0) *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
   desc.base = *rdata;
   desc.buflen = mdrcnt;
   desc.subformat = NULL;
@@ -2928,11 +2978,11 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
     {
       fstring mypath;
       fstrcpy(mypath,"\\\\");
-      fstrcat(mypath,local_machine);
-      strupper(mypath);
+      fstrcat(mypath,get_local_machine_name());
+      strupper_m(mypath);
       PACKS(&desc,"z",mypath); /* computer */
     }
-    PACKS(&desc,"z",global_myworkgroup);/* domain */
+    PACKS(&desc,"z",lp_workgroup());/* domain */
 
     PACKS(&desc,"z", vuser && vuser->logon_script ? vuser->logon_script :"");          /* script path */
 
@@ -2941,7 +2991,7 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
 
   *rdata_len = desc.usedlen;
   *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVALS(*rparam,0,desc.errcode);
   SSVAL(*rparam,2,0);
   SSVAL(*rparam,4,desc.neededlen);
@@ -2950,10 +3000,10 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
   return(True);
 }
 
-
 /****************************************************************************
-  api_WAccessGetUserPerms
-  ****************************************************************************/
+ api_WAccessGetUserPerms
+****************************************************************************/
+
 static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid, char *param,char *data,
                                    int mdrcnt,int mprcnt,
                                    char **rdata,char **rparam,
@@ -2971,7 +3021,7 @@ static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid, char *p
   if (strcmp(str2,"") != 0) return False;
 
   *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVALS(*rparam,0,0);         /* errorcode */
   SSVAL(*rparam,2,0);          /* converter word */
   SSVAL(*rparam,4,0x7f);       /* permission flags */
@@ -2982,6 +3032,7 @@ 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,
@@ -2994,6 +3045,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
   int count;
   int i;
   int snum;
+  fstring sharename;
   uint32 jobid;
   struct pack_desc desc;
   print_queue_struct *queue=NULL;
@@ -3011,9 +3063,10 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
   if (strcmp(str1,"WWrLh") != 0) return False;
   if (!check_printjob_info(&desc,uLevel,str2)) return False;
 
-  jobid = rap_to_pjobid(SVAL(p,0));
-  snum = print_job_snum(jobid);
+  if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
+    return False;
 
+  snum = lp_servicenumber( sharename);
   if (snum < 0 || !VALID_SNUM(snum)) return(False);
 
   count = print_queue_status(snum,&queue,&status);
@@ -3022,7 +3075,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
   }
 
   if (mdrcnt > 0) {
-    *rdata = REALLOC(*rdata,mdrcnt);
+    *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
     desc.base = *rdata;
     desc.buflen = mdrcnt;
   } else {
@@ -3031,7 +3084,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
      *  init_package will return wrong size if buflen=0
      */
     desc.buflen = getlen(desc.format);
-    desc.base = tmpdata = (char *)malloc ( desc.buflen );
+    desc.base = tmpdata = (char *)SMB_MALLOC( desc.buflen );
   }
 
   if (init_package(&desc,1,0)) {
@@ -3046,7 +3099,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
   }
 
   *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVALS(*rparam,0,desc.errcode);
   SSVAL(*rparam,2,0);
   SSVAL(*rparam,4,desc.neededlen);
@@ -3084,23 +3137,21 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
   DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
 
   /* check it's a supported variant */
-  if (strcmp(str1,"zWrLeh") != 0) return False;
-  if (uLevel > 2) return False;        /* defined only for uLevel 0,1,2 */
-  if (!check_printjob_info(&desc,uLevel,str2)) return False;
-
-  snum = lp_servicenumber(name);
-  if (snum < 0 && pcap_printername_ok(name,NULL)) {
-    int pnum = lp_servicenumber(PRINTERS_NAME);
-    if (pnum >= 0) {
-      lp_add_printer(name,pnum);
-      snum = lp_servicenumber(name);
-    }
-  }
+  if (strcmp(str1,"zWrLeh") != 0) 
+    return False;
+    
+  if (uLevel > 2) 
+    return False;      /* defined only for uLevel 0,1,2 */
+    
+  if (!check_printjob_info(&desc,uLevel,str2)) 
+    return False;
 
-  if (snum < 0 || !VALID_SNUM(snum)) return(False);
+  snum = find_service(name);
+  if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
+    return False;
 
   count = print_queue_status(snum,&queue,&status);
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+  if (mdrcnt > 0) *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
   desc.base = *rdata;
   desc.buflen = mdrcnt;
 
@@ -3115,7 +3166,7 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
   *rdata_len = desc.usedlen;
 
   *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVALS(*rparam,0,desc.errcode);
   SSVAL(*rparam,2,0);
   SSVAL(*rparam,4,succnt);
@@ -3148,7 +3199,7 @@ static void fill_printdest_info(connection_struct *conn, int snum, int uLevel,
   char buf[100];
   strncpy(buf,SERVICE(snum),sizeof(buf)-1);
   buf[sizeof(buf)-1] = 0;
-  strupper(buf);
+  strupper_m(buf);
   if (uLevel <= 1) {
     PACKS(desc,"B9",buf);      /* szName */
     if (uLevel == 1) {
@@ -3200,23 +3251,15 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
   if (strcmp(str1,"zWrLh") != 0) return False;
   if (!check_printdest_info(&desc,uLevel,str2)) return False;
 
-  snum = lp_servicenumber(PrinterName);
-  if (snum < 0 && pcap_printername_ok(PrinterName,NULL)) {
-    int pnum = lp_servicenumber(PRINTERS_NAME);
-    if (pnum >= 0) {
-      lp_add_printer(PrinterName,pnum);
-      snum = lp_servicenumber(PrinterName);
-    }
-  }
-
-  if (snum < 0) {
+  snum = find_service(PrinterName);
+  if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) {
     *rdata_len = 0;
     desc.errcode = NERR_DestNotFound;
     desc.neededlen = 0;
   }
   else {
     if (mdrcnt > 0) {
-      *rdata = REALLOC(*rdata,mdrcnt);
+      *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
       desc.base = *rdata;
       desc.buflen = mdrcnt;
     } else {
@@ -3225,7 +3268,7 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
        *  init_package will return wrong size if buflen=0
        */
       desc.buflen = getlen(desc.format);
-      desc.base = tmpdata = (char *)malloc ( desc.buflen );
+      desc.base = tmpdata = (char *)SMB_MALLOC( desc.buflen );
     }
     if (init_package(&desc,1,0)) {
       fill_printdest_info(conn,snum,uLevel,&desc);
@@ -3234,7 +3277,7 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
   }
 
   *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVALS(*rparam,0,desc.errcode);
   SSVAL(*rparam,2,0);
   SSVAL(*rparam,4,desc.neededlen);
@@ -3273,7 +3316,7 @@ static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,
     if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
       queuecnt++;
 
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+  if (mdrcnt > 0) *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
   desc.base = *rdata;
   desc.buflen = mdrcnt;
   if (init_package(&desc,queuecnt,0)) {    
@@ -3291,7 +3334,7 @@ static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,
   *rdata_len = desc.usedlen;
 
   *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVALS(*rparam,0,desc.errcode);
   SSVAL(*rparam,2,0);
   SSVAL(*rparam,4,succnt);
@@ -3323,7 +3366,7 @@ static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *para
   if (strcmp(str1,"WrLeh") != 0) return False;
   if (uLevel != 0 || strcmp(str2,"B41") != 0) return False;
 
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+  if (mdrcnt > 0) *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
   desc.base = *rdata;
   desc.buflen = mdrcnt;
   if (init_package(&desc,1,0)) {
@@ -3335,7 +3378,7 @@ static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *para
   *rdata_len = desc.usedlen;
 
   *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVALS(*rparam,0,desc.errcode);
   SSVAL(*rparam,2,0);
   SSVAL(*rparam,4,succnt);
@@ -3367,7 +3410,7 @@ static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param
   if (strcmp(str1,"WrLeh") != 0) return False;
   if (uLevel != 0 || strcmp(str2,"B13") != 0) return False;
 
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+  if (mdrcnt > 0) *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
   desc.base = *rdata;
   desc.buflen = mdrcnt;
   desc.format = str2;
@@ -3380,7 +3423,7 @@ static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param
   *rdata_len = desc.usedlen;
 
   *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVALS(*rparam,0,desc.errcode);
   SSVAL(*rparam,2,0);
   SSVAL(*rparam,4,succnt);
@@ -3412,7 +3455,7 @@ static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,
   if (strcmp(str1,"WrLeh") != 0) return False;
   if (uLevel != 0 || strcmp(str2,"B9") != 0) return False;
 
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+  if (mdrcnt > 0) *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
   memset((char *)&desc,'\0',sizeof(desc));
   desc.base = *rdata;
   desc.buflen = mdrcnt;
@@ -3426,7 +3469,7 @@ static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,
   *rdata_len = desc.usedlen;
 
   *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVALS(*rparam,0,desc.errcode);
   SSVAL(*rparam,2,0);
   SSVAL(*rparam,4,succnt);
@@ -3468,7 +3511,7 @@ static BOOL api_RNetSessionEnum(connection_struct *conn,uint16 vuid, char *param
 
   num_sessions = list_sessions(&session_list);
 
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+  if (mdrcnt > 0) *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
   memset((char *)&desc,'\0',sizeof(desc));
   desc.base = *rdata;
   desc.buflen = mdrcnt;
@@ -3492,7 +3535,7 @@ static BOOL api_RNetSessionEnum(connection_struct *conn,uint16 vuid, char *param
   *rdata_len = desc.usedlen;
 
   *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
+  *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
   SSVALS(*rparam,0,desc.errcode);
   SSVAL(*rparam,2,0); /* converter */
   SSVAL(*rparam,4,num_sessions); /* count */
@@ -3503,99 +3546,95 @@ static BOOL api_RNetSessionEnum(connection_struct *conn,uint16 vuid, char *param
 
 
 /****************************************************************************
- The buffer was too small
+ The buffer was too small.
  ****************************************************************************/
 
-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 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 = REALLOC(*rparam,*rparam_len);
+       *rparam_len = MIN(*rparam_len,mprcnt);
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
 
-  *rdata_len = 0;
+       *rdata_len = 0;
 
-  SSVAL(*rparam,0,NERR_BufTooSmall);
+       SSVAL(*rparam,0,NERR_BufTooSmall);
 
-  DEBUG(3,("Supplied buffer too small in API command\n"));
+       DEBUG(3,("Supplied buffer too small in API command\n"));
 
-  return(True);
+       return True;
 }
 
-
 /****************************************************************************
- The request is not supported
+ 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, char *data,
+                           int mdrcnt, int mprcnt,
+                           char **rdata, char **rparam,
+                           int *rdata_len, int *rparam_len)
 {
-  *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam_len = 4;
+       *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
 
-  *rdata_len = 0;
+       *rdata_len = 0;
 
-  SSVAL(*rparam,0,NERR_notsupported);
-  SSVAL(*rparam,2,0);          /* converter word */
+       SSVAL(*rparam,0,NERR_notsupported);
+       SSVAL(*rparam,2,0);             /* converter word */
 
-  DEBUG(3,("Unsupported API command\n"));
+       DEBUG(3,("Unsupported API command\n"));
 
-  return(True);
+       return True;
 }
 
-
-
-
-struct
-{
-  char *name;
-  int id;
-  BOOL (*fn)(connection_struct *,uint16,char *,char *,
-            int,int,char **,char **,int *,int *);
-  BOOL auth_user;              /* Deny anonymous access? */
+static const struct {
+       const char *name;
+       int id;
+       BOOL (*fn)(connection_struct *,uint16,char *,char *,
+                       int,int,char **,char **,int *,int *);
+       BOOL auth_user;         /* Deny anonymous access? */
 } api_commands[] = {
-  {"RNetShareEnum",    RAP_WshareEnum,         api_RNetShareEnum, True},
-  {"RNetShareGetInfo", RAP_WshareGetInfo,      api_RNetShareGetInfo},
-  {"RNetShareAdd",     RAP_WshareAdd,          api_RNetShareAdd},
-  {"RNetSessionEnum",  RAP_WsessionEnum,       api_RNetSessionEnum, True},
-  {"RNetServerGetInfo",        RAP_WserverGetInfo,     api_RNetServerGetInfo},
-  {"RNetGroupEnum",    RAP_WGroupEnum,         api_RNetGroupEnum, True},
-  {"RNetGroupGetUsers", RAP_WGroupGetUsers,    api_RNetGroupGetUsers, True},
-  {"RNetUserEnum",     RAP_WUserEnum,          api_RNetUserEnum, True},
-  {"RNetUserGetInfo",  RAP_WUserGetInfo,       api_RNetUserGetInfo},
-  {"NetUserGetGroups", RAP_WUserGetGroups,     api_NetUserGetGroups},
-  {"NetWkstaGetInfo",  RAP_WWkstaGetInfo,      api_NetWkstaGetInfo},
-  {"DosPrintQEnum",    RAP_WPrintQEnum,        api_DosPrintQEnum, True},
-  {"DosPrintQGetInfo", RAP_WPrintQGetInfo,     api_DosPrintQGetInfo},
-  {"WPrintQueuePause",  RAP_WPrintQPause,      api_WPrintQueueCtrl},
-  {"WPrintQueueResume", RAP_WPrintQContinue,   api_WPrintQueueCtrl},
-  {"WPrintJobEnumerate",RAP_WPrintJobEnum,     api_WPrintJobEnumerate},
-  {"WPrintJobGetInfo", RAP_WPrintJobGetInfo,   api_WPrintJobGetInfo},
-  {"RDosPrintJobDel",  RAP_WPrintJobDel,       api_RDosPrintJobDel},
-  {"RDosPrintJobPause",        RAP_WPrintJobPause,     api_RDosPrintJobDel},
-  {"RDosPrintJobResume",RAP_WPrintJobContinue, api_RDosPrintJobDel},
-  {"WPrintDestEnum",   RAP_WPrintDestEnum,     api_WPrintDestEnum},
-  {"WPrintDestGetInfo",        RAP_WPrintDestGetInfo,  api_WPrintDestGetInfo},
-  {"NetRemoteTOD",     RAP_NetRemoteTOD,       api_NetRemoteTOD},
-  {"WPrintQueuePurge", RAP_WPrintQPurge,       api_WPrintQueueCtrl},
-  {"NetServerEnum",    RAP_NetServerEnum2,     api_RNetServerEnum}, /* anon OK */
-  {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms},
-  {"SetUserPassword",  RAP_WUserPasswordSet2,  api_SetUserPassword},
-  {"WWkstaUserLogon",  RAP_WWkstaUserLogon,    api_WWkstaUserLogon},
-  {"PrintJobInfo",     RAP_WPrintJobSetInfo,   api_PrintJobInfo},
-  {"WPrintDriverEnum", RAP_WPrintDriverEnum,   api_WPrintDriverEnum},
-  {"WPrintQProcEnum",  RAP_WPrintQProcessorEnum,api_WPrintQProcEnum},
-  {"WPrintPortEnum",   RAP_WPrintPortEnum,     api_WPrintPortEnum},
-  {"SamOEMChangePassword",RAP_SamOEMChgPasswordUser2_P,api_SamOEMChangePassword}, /* anon OK */
-  {NULL,               -1,     api_Unsupported}};
-
-/*  The following RAP calls are not implemented by Samba:
-
-        RAP_WFileEnum2 - anon not OK 
-*/
+       {"RNetShareEnum",       RAP_WshareEnum,         api_RNetShareEnum, True},
+       {"RNetShareGetInfo",    RAP_WshareGetInfo,      api_RNetShareGetInfo},
+       {"RNetShareAdd",        RAP_WshareAdd,          api_RNetShareAdd},
+       {"RNetSessionEnum",     RAP_WsessionEnum,       api_RNetSessionEnum, True},
+       {"RNetServerGetInfo",   RAP_WserverGetInfo,     api_RNetServerGetInfo},
+       {"RNetGroupEnum",       RAP_WGroupEnum,         api_RNetGroupEnum, True},
+       {"RNetGroupGetUsers", RAP_WGroupGetUsers,       api_RNetGroupGetUsers, True},
+       {"RNetUserEnum",        RAP_WUserEnum,          api_RNetUserEnum, True},
+       {"RNetUserGetInfo",     RAP_WUserGetInfo,       api_RNetUserGetInfo},
+       {"NetUserGetGroups",    RAP_WUserGetGroups,     api_NetUserGetGroups},
+       {"NetWkstaGetInfo",     RAP_WWkstaGetInfo,      api_NetWkstaGetInfo},
+       {"DosPrintQEnum",       RAP_WPrintQEnum,        api_DosPrintQEnum, True},
+       {"DosPrintQGetInfo",    RAP_WPrintQGetInfo,     api_DosPrintQGetInfo},
+       {"WPrintQueuePause",  RAP_WPrintQPause, api_WPrintQueueCtrl},
+       {"WPrintQueueResume", RAP_WPrintQContinue,      api_WPrintQueueCtrl},
+       {"WPrintJobEnumerate",RAP_WPrintJobEnum,        api_WPrintJobEnumerate},
+       {"WPrintJobGetInfo",    RAP_WPrintJobGetInfo,   api_WPrintJobGetInfo},
+       {"RDosPrintJobDel",     RAP_WPrintJobDel,       api_RDosPrintJobDel},
+       {"RDosPrintJobPause",   RAP_WPrintJobPause,     api_RDosPrintJobDel},
+       {"RDosPrintJobResume",RAP_WPrintJobContinue,    api_RDosPrintJobDel},
+       {"WPrintDestEnum",      RAP_WPrintDestEnum,     api_WPrintDestEnum},
+       {"WPrintDestGetInfo",   RAP_WPrintDestGetInfo,  api_WPrintDestGetInfo},
+       {"NetRemoteTOD",        RAP_NetRemoteTOD,       api_NetRemoteTOD},
+       {"WPrintQueuePurge",    RAP_WPrintQPurge,       api_WPrintQueueCtrl},
+       {"NetServerEnum",       RAP_NetServerEnum2,     api_RNetServerEnum}, /* anon OK */
+       {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms},
+       {"SetUserPassword",     RAP_WUserPasswordSet2,  api_SetUserPassword},
+       {"WWkstaUserLogon",     RAP_WWkstaUserLogon,    api_WWkstaUserLogon},
+       {"PrintJobInfo",        RAP_WPrintJobSetInfo,   api_PrintJobInfo},
+       {"WPrintDriverEnum",    RAP_WPrintDriverEnum,   api_WPrintDriverEnum},
+       {"WPrintQProcEnum",     RAP_WPrintQProcessorEnum,api_WPrintQProcEnum},
+       {"WPrintPortEnum",      RAP_WPrintPortEnum,     api_WPrintPortEnum},
+       {"SamOEMChangePassword",RAP_SamOEMChgPasswordUser2_P,api_SamOEMChangePassword}, /* anon OK */
+       {NULL,          -1,     api_Unsupported}
+       /*  The following RAP calls are not implemented by Samba:
+
+       RAP_WFileEnum2 - anon not OK 
+       */
+};
+
 
 /****************************************************************************
  Handle remote api calls
@@ -3604,75 +3643,79 @@ struct
 int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
                     int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
 {
-  int api_command;
-  char *rdata = NULL;
-  char *rparam = NULL;
-  int rdata_len = 0;
-  int rparam_len = 0;
-  BOOL reply=False;
-  int i;
+       int api_command;
+       char *rdata = NULL;
+       char *rparam = NULL;
+       int rdata_len = 0;
+       int rparam_len = 0;
+       BOOL reply=False;
+       int i;
 
-  if (!params) {
-         DEBUG(0,("ERROR: NULL params in api_reply()\n"));
-         return 0;
-  }
+       if (!params) {
+               DEBUG(0,("ERROR: NULL params in api_reply()\n"));
+               return 0;
+       }
 
-  api_command = SVAL(params,0);
+       api_command = SVAL(params,0);
 
-  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),
-          tdscnt,tpscnt,mdrcnt,mprcnt));
+       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),
+               tdscnt,tpscnt,mdrcnt,mprcnt));
 
-  for (i=0;api_commands[i].name;i++) {
-    if (api_commands[i].id == api_command && api_commands[i].fn) {
-        DEBUG(3,("Doing %s\n",api_commands[i].name));
-        break;
-    }
-  }
+       for (i=0;api_commands[i].name;i++) {
+               if (api_commands[i].id == api_command && api_commands[i].fn) {
+                       DEBUG(3,("Doing %s\n",api_commands[i].name));
+                       break;
+               }
+       }
 
-  /* Check whether this api call can be done anonymously */
+       /* Check whether this api call can be done anonymously */
 
-  if (api_commands[i].auth_user && lp_restrict_anonymous()) {
-         user_struct *user = get_valid_user_struct(vuid);
+       if (api_commands[i].auth_user && lp_restrict_anonymous()) {
+               user_struct *user = get_valid_user_struct(vuid);
 
-         if (!user || user->guest)
-                 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
-  }
+               if (!user || user->guest) {
+                       return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+               }
+       }
 
-  rdata = (char *)malloc(1024);
-  if (rdata)
-    memset(rdata,'\0',1024);
+       rdata = (char *)SMB_MALLOC(1024);
+       if (rdata) {
+               memset(rdata,'\0',1024);
+       }
 
-  rparam = (char *)malloc(1024);
-  if (rparam)
-    memset(rparam,'\0',1024);
+       rparam = (char *)SMB_MALLOC(1024);
+       if (rparam) {
+               memset(rparam,'\0',1024);
+       }
 
-  if(!rdata || !rparam) {
-    DEBUG(0,("api_reply: malloc fail !\n"));
-    return -1;
-  }
+       if(!rdata || !rparam) {
+               DEBUG(0,("api_reply: malloc fail !\n"));
+               SAFE_FREE(rdata);
+               SAFE_FREE(rparam);
+               return -1;
+       }
 
-  reply = api_commands[i].fn(conn,vuid,params,data,mdrcnt,mprcnt,
-                            &rdata,&rparam,&rdata_len,&rparam_len);
+       reply = api_commands[i].fn(conn,vuid,params,data,mdrcnt,mprcnt,
+                               &rdata,&rparam,&rdata_len,&rparam_len);
 
 
-  if (rdata_len > mdrcnt ||
-      rparam_len > mprcnt) {
-      reply = api_TooSmall(conn,vuid,params,data,mdrcnt,mprcnt,
-                          &rdata,&rparam,&rdata_len,&rparam_len);
-  }
+       if (rdata_len > mdrcnt || rparam_len > mprcnt) {
+               reply = api_TooSmall(conn,vuid,params,data,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,
-                   &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,
+                       &rdata,&rparam,&rdata_len,&rparam_len);
+       }
 
-  send_trans_reply(outbuf, rparam, rparam_len, rdata, rdata_len, False);
+       send_trans_reply(outbuf, rparam, rparam_len, rdata, rdata_len, False);
 
-  SAFE_FREE(rdata);
-  SAFE_FREE(rparam);
-  
-  return -1;
+       SAFE_FREE(rdata);
+       SAFE_FREE(rparam);
+       return -1;
 }