I have fixed quite a few important bugs in this commit.
authorAndrew Tridgell <tridge@samba.org>
Sat, 5 Oct 1996 10:41:13 +0000 (10:41 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sat, 5 Oct 1996 10:41:13 +0000 (10:41 +0000)
Luke, can you take special note of the bug fixes to nmbd so you can
propogate them to your new code.

- rewrote the code that used to use fromhost(). We now call
gethostbyaddr() only if necessary and a maximum of once per
connection. Calling gethostbyaddr() causes problems on some systems so
avoiding it if possible is a good thing :-)

- added the "fake oplocks" option. See the docs in smb.conf(5) and
Speed.txt

- fixed a serious bug in nmbd where it would try a DNS lookup on
FIND_SELF queries. This caused a lot of unnecessary (and incorrect)
DNS lookups to happen. FIND_SELF queries should only go to the
internal name tables.

- don't set FIND_SELF for name queries if we are a wins proxy, as we
are supposed to be answering queries for other hosts.

- fixed a bug in nmbd which had "if (search | FIND_LOCAL)" instead of
"if (search & FIND_LOCAL)". Luke, this was in nameservreply.c

- the above 3 bugs together meant that DNS queries were being cached,
but the cache wasn't being used, so every query was going to DNS, no
wonder nmbd has been chewing so much CPU time! Another side effect was
that queries on names in lmhosts weren't being answered for bcast
queries with "wins proxy" set.

- ignore the maxxmit for seconday session setups (see CIFS spec)

- close user opened files in a uLogoffX for user level security (see
CIFS spec)

- added uid into the files struct to support the above change

12 files changed:
source/include/proto.h
source/include/smb.h
source/lib/access.c
source/lib/util.c
source/namedbname.c
source/nameservreply.c
source/param/loadparm.c
source/smbd/password.c
source/smbd/reply.c
source/smbd/server.c
source/smbd/trans2.c
source/utils/testparm.c

index 779f6bd87edbc5438df72586526d465578f59777..8c082a6140b69954eb2e3058591e2f4314aec21e 100644 (file)
@@ -4,8 +4,7 @@
 /*The following definitions come from  access.c  */
 
 BOOL check_access(int snum);
-BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
-BOOL fromhost(int sock,struct from_host *f);
+BOOL allow_access(char *deny_list,char *allow_list,char *cname,char *caddr);
 
 /*The following definitions come from  charcnv.c  */
 
@@ -234,6 +233,7 @@ BOOL lp_widelinks(int );
 BOOL lp_syncalways(int );
 BOOL lp_map_system(int );
 BOOL lp_delete_readonly(int );
+BOOL lp_fake_oplocks(int );
 int lp_create_mode(int );
 int lp_max_connections(int );
 int lp_defaultcase(int );
@@ -913,6 +913,8 @@ int interpret_security(char *str,int def);
 uint32 interpret_addr(char *str);
 struct in_addr *interpret_addr2(char *str);
 BOOL zero_ip(struct in_addr ip);
+char *client_name(void);
+char *client_addr(void);
 void standard_sub_basic(char *s);
 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
 int PutUniCode(char *dst,char *src);
index f5d35d5261e24e592f2ac6ad50f182dcda53b9be..af6e24c4aba1add34a67ff467ec1d5311f53e3e2 100644 (file)
@@ -293,6 +293,7 @@ typedef struct
   int pos;
   int size;
   int mode;
+  int uid;
   char *mmap_ptr;
   int mmap_size;
   write_bmpx_struct *wbmpx_ptr;
@@ -653,13 +654,6 @@ struct connect_record
 #define ERRHRD 0x03  /* Error is an hardware error. */
 #define ERRCMD 0xFF  /* Command was not in the "SMB" format. */
 
-/* structure used to hold the incoming hosts info */
-struct from_host {
-    char   *name;                      /* host name */
-    char   *addr;                      /* host address */
-    struct sockaddr_in *sin;           /* their side of the link */
-};
-
 #ifdef __STDC__
 int Debug1(char *, ...);
 #else
index 8f57c37c26f4f1be3963ffccd544cfed423aee12..3b3f236c91ac7f3bedad8a21a5d2d8cbc2347c8e 100644 (file)
@@ -19,7 +19,6 @@ extern int DEBUGLEVEL;
 #endif
 
 
-#define FROM_ADDRLEN  (4*3+3+1)
 #define Good True
 #define Bad False
 
@@ -40,17 +39,13 @@ static int list_match(char *list,char *item, int (*match_fn)());
 static int client_match(char *tok,char *item);
 static int string_match(char *tok,char *s);
 static int masked_match(char *tok, char *slash, char *s);
-static int matchname(char *remotehost,struct in_addr  addr);
 
 /* Size of logical line buffer. */
 #define        BUFLEN 2048
 
-
 /* return true if access should be allowed to a service*/
 BOOL check_access(int snum)
 {
-  extern int Client;
-  extern struct from_host Client_info;
   char *denyl,*allowl;
   BOOL ret = False;
 
@@ -60,32 +55,24 @@ BOOL check_access(int snum)
   allowl = lp_hostsallow(snum);
   if (allowl) allowl = strdup(allowl);
 
-
-  fromhost(Client,&Client_info);
-
   if ((!denyl || *denyl==0) && (!allowl || *allowl==0))
     ret = True;
 
   if (!ret)
     {
-      if (!fromhost(Client,&Client_info))
-       DEBUG(0,("ERROR: Can't get from_host info\n"));
-      else
+      if (allow_access(denyl,allowl,client_name(),client_addr()))
        {
-         if (allow_access(denyl,allowl,&Client_info))
-           {
-             if (snum >= 0)
-               DEBUG(2,("Allowed connection from %s (%s) to %s\n",
-                        Client_info.name,Client_info.addr,
-                        lp_servicename(snum)));
-             ret = True;
-           }
-         else
-           if (snum >= 0)
-             DEBUG(0,("Denied connection from %s (%s) to %s\n",
-                      Client_info.name,Client_info.addr,
-                      lp_servicename(snum)));
+         if (snum >= 0)
+           DEBUG(2,("Allowed connection from %s (%s) to %s\n",
+                    client_name(),client_addr(),
+                    lp_servicename(snum)));
+         ret = True;
        }
+      else
+       if (snum >= 0)
+         DEBUG(0,("Denied connection from %s (%s) to %s\n",
+                  client_name(),client_addr(),
+                  lp_servicename(snum)));
     }
 
   if (denyl) free(denyl);
@@ -95,8 +82,13 @@ BOOL check_access(int snum)
 
 
 /* return true if access should be allowed */
-BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client)
+BOOL allow_access(char *deny_list,char *allow_list,char *cname,char *caddr)
 {
+  char *client[2];
+
+  client[0] = cname;
+  client[1] = caddr;  
+
   /* if theres no deny list and no allow list then allow access */
   if ((!deny_list || *deny_list == 0) && (!allow_list || *allow_list == 0))
     return(True);  
@@ -171,7 +163,7 @@ static int list_match(char *list,char *item, int (*match_fn)())
 /* client_match - match host name and address against token */
 static int client_match(char *tok,char *item)
 {
-    struct from_host *client = (struct from_host *) item;
+    char **client = (char **)item;
     int     match;
 
     /*
@@ -179,9 +171,9 @@ static int client_match(char *tok,char *item)
      * name if available.
      */
 
-    if ((match = string_match(tok, client->addr)) == 0)
-       if (client->name[0] != 0)
-           match = string_match(tok, client->name);
+    if ((match = string_match(tok, client[1])) == 0)
+       if (client[0][0] != 0)
+           match = string_match(tok, client[0]);
     return (match);
 }
 
@@ -289,97 +281,5 @@ static int masked_match(char *tok, char *slash, char *s)
 }
 
 
-/* fromhost - find out what is at the other end of a socket */
-BOOL fromhost(int sock,struct from_host *f)
-{
-    static struct sockaddr sa;
-    struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
-    struct hostent *hp;
-    int     length = sizeof(sa);
-    static char addr_buf[FROM_ADDRLEN];
-    static char name_buf[MAXHOSTNAMELEN];
-    BOOL   takeAddressAsHostname = False;
-
-    if (getpeername(sock, &sa, &length) < 0) 
-      {
-       DEBUG(0,("getpeername failed\n"));
-       return(False);
-      }
-
-    f->sin = sockin;
-    f->addr = strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
-
-    /* Look up the remote host name. */
-    if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
-                           sizeof(sockin->sin_addr),
-                           AF_INET)) == 0) {
-      DEBUG(1,("Gethostbyaddr failed for %s\n",addr_buf));
-#ifdef ALLOW_PURE_ADDRESSES
-      takeAddressAsHostname = True;
-#else
-      return(False);
-#endif
-    }
-
-    /* Save the host name. A later gethostbyxxx() call may clobber it. */
-    f->name = StrnCpy(name_buf,
-                      takeAddressAsHostname? f->addr : hp->h_name,
-                      sizeof(name_buf) - 1);
-
-    /*
-     * Verify that the host name does not belong to someone else. If host
-     * name verification fails, pretend that the host name lookup failed.
-     */
-    if (!takeAddressAsHostname && !matchname(f->name, sockin->sin_addr))
-      {
-       DEBUG(0,("Matchname failed\n"));
-       return(False);
-      }
-
-    return(True);      
-}
-
-/* matchname - determine if host name matches IP address */
-static int matchname(char *remotehost,struct in_addr  addr)
-{
-  struct hostent *hp;
-  int     i;
-  
-  if ((hp = Get_Hostbyname(remotehost)) == 0) {
-    DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
-    return (Bad);
-  } 
-
-    /*
-     * Make sure that gethostbyname() returns the "correct" host name.
-     * Unfortunately, gethostbyname("localhost") sometimes yields
-     * "localhost.domain". Since the latter host name comes from the
-     * local DNS, we just have to trust it (all bets are off if the local
-     * DNS is perverted). We always check the address list, though.
-     */
-  
-  if (strcasecmp(remotehost, hp->h_name)
-      && strcasecmp(remotehost, "localhost")) {
-    DEBUG(0,("host name/name mismatch: %s != %s",
-         remotehost, hp->h_name));
-    return (Bad);
-  }
-       
-  /* Look up the host address in the address list we just got. */
-  for (i = 0; hp->h_addr_list[i]; i++) {
-    if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
-      return (Good);
-  }
-
-  /*
-   * The host name does not map to the original host address. Perhaps
-   * someone has compromised a name server. More likely someone botched
-   * it, but that could be dangerous, too.
-   */
-  
-  DEBUG(0,("host name/address mismatch: %s != %s",
-       inet_ntoa(addr), hp->h_name));
-  return (Bad);
-}
 
 
index efe91a5046830765a400131dd2ecd7c6b25632d7..d82dbddb4460e4d6c04eb1f680342bb085ba4f26 100644 (file)
@@ -38,10 +38,6 @@ FILE *dbf = NULL;
 /* the client file descriptor */
 int Client = -1;
 
-/* info on the client */
-struct from_host Client_info=
-{"UNKNOWN","0.0.0.0",NULL};
-
 /* the last IP received from */
 struct in_addr lastip;
 
@@ -3009,6 +3005,114 @@ BOOL zero_ip(struct in_addr ip)
   return(a == 0);
 }
 
+
+/* matchname - determine if host name matches IP address */
+static BOOL matchname(char *remotehost,struct in_addr  addr)
+{
+  struct hostent *hp;
+  int     i;
+  
+  if ((hp = Get_Hostbyname(remotehost)) == 0) {
+    DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
+    return False;
+  } 
+
+  /*
+   * Make sure that gethostbyname() returns the "correct" host name.
+   * Unfortunately, gethostbyname("localhost") sometimes yields
+   * "localhost.domain". Since the latter host name comes from the
+   * local DNS, we just have to trust it (all bets are off if the local
+   * DNS is perverted). We always check the address list, though.
+   */
+  
+  if (strcasecmp(remotehost, hp->h_name)
+      && strcasecmp(remotehost, "localhost")) {
+    DEBUG(0,("host name/name mismatch: %s != %s",
+            remotehost, hp->h_name));
+    return False;
+  }
+       
+  /* Look up the host address in the address list we just got. */
+  for (i = 0; hp->h_addr_list[i]; i++) {
+    if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
+      return True;
+  }
+
+  /*
+   * The host name does not map to the original host address. Perhaps
+   * someone has compromised a name server. More likely someone botched
+   * it, but that could be dangerous, too.
+   */
+  
+  DEBUG(0,("host name/address mismatch: %s != %s",
+          inet_ntoa(addr), hp->h_name));
+  return False;
+}
+
+/* return the DNS name of the client */
+char *client_name(void)
+{
+  extern int Client;
+  struct sockaddr sa;
+  struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
+  int     length = sizeof(sa);
+  static pstring name_buf;
+  static BOOL done = False;
+  struct hostent *hp;
+
+  if (done) 
+    return name_buf;
+
+  done = True;
+  strcpy(name_buf,"UNKNOWN");
+
+  if (getpeername(Client, &sa, &length) < 0) {
+    DEBUG(0,("getpeername failed\n"));
+    return name_buf;
+  }
+
+  /* Look up the remote host name. */
+  if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
+                         sizeof(sockin->sin_addr),
+                         AF_INET)) == 0) {
+    DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
+    StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
+  } else {
+    StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
+    if (!matchname(name_buf, sockin->sin_addr)) {
+      DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
+      strcpy(name_buf,"UNKNOWN");
+    }
+  }
+  return name_buf;
+}
+
+/* return the IP addr of the client as a string */
+char *client_addr(void)
+{
+  extern int Client;
+  struct sockaddr sa;
+  struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
+  int     length = sizeof(sa);
+  static fstring addr_buf;
+  static BOOL done = False;
+
+  if (done) 
+    return addr_buf;
+
+  done = True;
+  strcpy(addr_buf,"0.0.0.0");
+
+  if (getpeername(Client, &sa, &length) < 0) {
+    DEBUG(0,("getpeername failed\n"));
+    return addr_buf;
+  }
+
+  strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
+
+  return addr_buf;
+}
+
 /*******************************************************************
 sub strings with useful parameters
 ********************************************************************/
@@ -3029,8 +3133,9 @@ void standard_sub_basic(char *s)
 
   if (!strchr(s,'%')) return;
 
-  string_sub(s,"%I",Client_info.addr);
-  string_sub(s,"%M",Client_info.name);
+  string_sub(s,"%I",client_addr());
+  if (strstr(s,"%M"))
+    string_sub(s,"%M",client_name());
   string_sub(s,"%T",timestring());
 
   if (!strchr(s,'%')) return;
index 1f16553b0f416e848041300dd20b0ae8dbd8468f..833a870c6cb4b9b279cc2f057d35327d47ccf26c 100644 (file)
@@ -150,7 +150,8 @@ struct name_record *find_name(struct name_record *n,
                if (name_equal(&ret->name,name))
                {
                        /* self search: self names only */
-                       if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
+                       if ((search&FIND_SELF) == FIND_SELF && 
+                           ret->source != SELF)
                                continue;
          
                        return ret;
@@ -528,13 +529,18 @@ struct name_record *search_for_name(struct subnet_record **d,
   
   if (*d == NULL) return NULL;
 
+  if (!n && (search & FIND_SELF)) {
+    DEBUG(3,("FIND_SELF set - failing lookup\n"));
+    return NULL;
+  }
+
   DEBUG(4,("subnet %s ", inet_ntoa((*d)->bcast_ip)));
 
   /* now try DNS lookup. */
   if (!n)
     {
       struct in_addr dns_ip;
-      uint32 a;
+      uint32 a;      
       
       /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
       if (!dns_type && name_type != 0x1b)
index b01c2c25b4cc51ec43fe18b57fbd2857230d0ecd..62b9ca0c49f6fa8d281ee9ec2b377560a2684f82 100644 (file)
@@ -507,14 +507,13 @@ void reply_name_query(struct packet_struct *p)
   /* directed queries are for WINS server: broadcasts are local SELF queries.
      the exception is Domain Master names.  */
 
-  int search = bcast ? FIND_LOCAL | FIND_SELF : FIND_WINS;
-  
-  if (name_type == 0x1b)
-  {
-    search |= FIND_WINS;
+  int search = bcast ? FIND_LOCAL | FIND_WINS: FIND_WINS;
+
+  if (!lp_wins_proxy()) {
+    search |= FIND_SELF;
   }
 
-  if (search | FIND_LOCAL)
+  if (search & FIND_LOCAL)
   {
     if (!(d = find_req_subnet(p->ip, bcast)))
     {
index 87209d1bb7c21fbac77c48fcefac695dac574e82..8b2806f0759b740e2d826219984dfed300a0e413 100644 (file)
@@ -242,6 +242,7 @@ typedef struct
   char magic_char;
   BOOL *copymap;
   BOOL bDeleteReadonly;
+  BOOL bFakeOplocks;
   char dummy[3]; /* for alignment */
 } service;
 
@@ -315,6 +316,7 @@ static service sDefault =
   '~',   /* magic char */
   NULL,  /* copymap */
   False, /* bDeleteReadonly */
+  False, /* bFakeOplocks */
   ""     /* dummy */
 };
 
@@ -493,6 +495,7 @@ struct parm_struct
   {"wide links",       P_BOOL,    P_LOCAL,  &sDefault.bWidelinks,       NULL},
   {"sync always",      P_BOOL,    P_LOCAL,  &sDefault.bSyncAlways,      NULL},
   {"mangled names",    P_BOOL,    P_LOCAL,  &sDefault.bMangledNames,    NULL},
+  {"fake oplocks",     P_BOOL,    P_LOCAL,  &sDefault.bFakeOplocks,     NULL},
   {"print command",    P_STRING,  P_LOCAL,  &sDefault.szPrintcommand,   NULL},
   {"lpq command",      P_STRING,  P_LOCAL,  &sDefault.szLpqcommand,     NULL},
   {"lprm command",     P_STRING,  P_LOCAL,  &sDefault.szLprmcommand,    NULL},
@@ -838,6 +841,7 @@ FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
 FN_LOCAL_BOOL(lp_map_system,bMap_system)
 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
+FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
 
 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mode)
 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
index 41dfd838ed1d3f9d6ec188bedc57ef68d183b063..d17bb86be4841f7f613904cebc892e48a3141d63 100644 (file)
@@ -1207,20 +1207,15 @@ BOOL check_hosts_equiv(char *user)
   pstring rhostsfile;
   struct passwd *pass = Get_Pwnam(user,True);
 
-  extern struct from_host Client_info;
-  extern int Client;
-
   if (!pass) 
     return(False);
 
-  fromhost(Client,&Client_info);
-
   fname = lp_hosts_equiv();
 
   /* note: don't allow hosts.equiv on root */
   if (fname && *fname && (pass->pw_uid != 0))
     {
-      if (check_user_equiv(user,Client_info.name,fname))
+      if (check_user_equiv(user,client_name(),fname))
        return(True);
     }
   
@@ -1230,7 +1225,7 @@ BOOL check_hosts_equiv(char *user)
       if (home)
        {
          sprintf(rhostsfile, "%s/.rhosts", home);
-         if (check_user_equiv(user,Client_info.name,rhostsfile))
+         if (check_user_equiv(user,client_name(),rhostsfile))
            return(True);
        }
     }
index 63c0a7027e15a65f9807d79e179cc1be57ccfa08..7b8f4a502feeeb74a51c389cddd7ef835e2c2956 100644 (file)
@@ -323,6 +323,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   pstring user;
   BOOL guest=False;
   BOOL computer_id=False;
+  static BOOL done_sesssetup = False;
 
   *smb_apasswd = 0;
   
@@ -489,7 +490,10 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
      to a uid can get through without a password, on the same VC */
   register_uid(SVAL(inbuf,smb_uid),gid,user,guest);
  
-  maxxmit = MIN(maxxmit,smb_bufsize);
+  if (!done_sesssetup)
+    maxxmit = MIN(maxxmit,smb_bufsize);
+
+  done_sesssetup = True;
 
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
@@ -983,6 +987,10 @@ int reply_open(char *inbuf,char *outbuf)
   put_dos_date3(outbuf,smb_vwv2,mtime);
   SIVAL(outbuf,smb_vwv4,size);
   SSVAL(outbuf,smb_vwv6,rmode);
+
+  if (lp_fake_oplocks(SNUM(cnum))) {
+    CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
+  }
     
   return(outsize);
 }
@@ -999,6 +1007,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   int openmode = 0;
   int smb_mode = SVAL(inbuf,smb_vwv3);
   int smb_attr = SVAL(inbuf,smb_vwv5);
+  BOOL oplock_request = BITSETW(inbuf+smb_vwv2,1);
 #if 0
   int open_flags = SVAL(inbuf,smb_vwv2);
   int smb_sattr = SVAL(inbuf,smb_vwv4); 
@@ -1053,6 +1062,10 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
     return(ERROR(ERRDOS,ERRnoaccess));
   }
 
+  if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+    smb_action |= (1<<15);
+  }
+
   set_message(outbuf,15,0,True);
   SSVAL(outbuf,smb_vwv2,fnum);
   SSVAL(outbuf,smb_vwv3,fmode);
@@ -1076,6 +1089,16 @@ int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize)
 
   invalidate_uid(uid);
 
+  /* in user level security we are supposed to close any files
+     open by this user */
+  if (lp_security() != SEC_SHARE) {
+    int i;
+    for (i=0;i<MAX_OPEN_FILES;i++)
+      if (Files[i].uid == uid && Files[i].open) {
+       close_file(i);
+      }
+  }
+
   set_message(outbuf,2,0,True);
 
   DEBUG(3,("%s ulogoffX uid=%d\n",timestring(),uid));
@@ -1127,6 +1150,10 @@ int reply_mknew(char *inbuf,char *outbuf)
   
   outsize = set_message(outbuf,1,0,True);
   SSVAL(outbuf,smb_vwv0,fnum);
+
+  if (lp_fake_oplocks(SNUM(cnum))) {
+    CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
+  }
   
   DEBUG(2,("new file %s\n",fname));
   DEBUG(3,("%s mknew %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname,Files[fnum].fd,fnum,cnum,createmode,unixmode));
@@ -1173,6 +1200,10 @@ int reply_ctemp(char *inbuf,char *outbuf)
   SSVAL(outbuf,smb_vwv0,fnum);
   CVAL(smb_buf(outbuf),0) = 4;
   strcpy(smb_buf(outbuf) + 1,fname2);
+
+  if (lp_fake_oplocks(SNUM(cnum))) {
+    CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
+  }
   
   DEBUG(2,("created temp file %s\n",fname2));
   DEBUG(3,("%s ctemp %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname2,Files[fnum].fd,fnum,cnum,createmode,unixmode));
index 9ad78404651a5bd5b5868471e44e586f6551d511..e0e9838a747ae56bbb59ee81e8692361c6533dd9 100644 (file)
@@ -714,6 +714,7 @@ open a file
 ****************************************************************************/
 void open_file(int fnum,int cnum,char *fname1,int flags,int mode)
 {
+  extern struct current_user current_user;
   pstring fname;
 
   Files[fnum].open = False;
@@ -826,6 +827,7 @@ void open_file(int fnum,int cnum,char *fname1,int flags,int mode)
       fstat(Files[fnum].fd,&st);
       Files[fnum].mode = st.st_mode;
       Files[fnum].open_time = time(NULL);
+      Files[fnum].uid = current_user.id;
       Files[fnum].size = 0;
       Files[fnum].pos = -1;
       Files[fnum].open = True;
@@ -2157,10 +2159,10 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
   unbecome_user();
 
   {
-    extern struct from_host Client_info;
     DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
                            timestring(),
-                           Client_info.name,Client_info.addr,
+                           remote_machine,
+                           client_addr(),
                            lp_servicename(SNUM(cnum)),user,
                            pcon->uid,
                            pcon->gid,
@@ -2597,8 +2599,6 @@ close a cnum
 ****************************************************************************/
 void close_cnum(int cnum, int uid)
 {
-  extern struct from_host Client_info;
-
   DirCacheFlush(SNUM(cnum));
 
   unbecome_user();
@@ -2611,7 +2611,7 @@ void close_cnum(int cnum, int uid)
 
   DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
                          timestring(),
-                         Client_info.name,Client_info.addr,
+                         remote_machine,client_addr(),
                          lp_servicename(SNUM(cnum))));
 
   yield_connection(cnum,
@@ -2825,11 +2825,8 @@ BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
   StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
   crec.start = time(NULL);
 
-  {
-    extern struct from_host Client_info;
-    StrnCpy(crec.machine,Client_info.name,sizeof(crec.machine)-1);
-    StrnCpy(crec.addr,Client_info.addr,sizeof(crec.addr)-1);
-  }
+  StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
+  StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
   
   /* make our mark */
   if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
@@ -2977,7 +2974,7 @@ struct smb_message_struct
    {SMBecho,"SMBecho",reply_echo,0},
    {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
    {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
-   {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, 
+   {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, AS_USER}, 
    {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
    {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
    {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
@@ -3350,11 +3347,8 @@ static void process(void)
 {
   static int trans_num = 0;
   int nread;
-  extern struct from_host Client_info;
   extern int Client;
 
-  fromhost(Client,&Client_info);
-  
   InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
   OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
   if ((InBuffer == NULL) || (OutBuffer == NULL)) 
index 9b5419010e2d68a5a09089c4e8b07ff11df6feb0..53af9acbf53f2ee9c558ed175bc4cd2b2b39a9fd 100644 (file)
@@ -163,6 +163,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
   char *params = *pparams;
   int16 open_mode = SVAL(params, 2);
   int16 open_attr = SVAL(params,6);
+  BOOL oplock_request = BITSETW(params,1);
 #if 0
   BOOL return_additional_info = BITSETW(params,0);
   int16 open_sattr = SVAL(params, 4);
@@ -232,6 +233,10 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
   SIVAL(params,8, size);
   SSVAL(params,12,rmode);
 
+  if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+    smb_action |= (1<<15);
+  }
+
   SSVAL(params,18,smb_action);
   SIVAL(params,20,inode);
  
index 1d6cc2b000333b315a80d630b231228bdfcfc08c..7e05283625d4559b7a24eb34b3c1919c62aac5b4 100644 (file)
@@ -87,23 +87,22 @@ extern int DEBUGLEVEL;
   
   if (argc == 4)
     {
-      struct from_host f;
-      f.name = argv[2];
-      f.addr = argv[3];
+      char *cname = argv[2];
+      char *caddr = argv[3];
       
       /* this is totally ugly, a real `quick' hack */
       for (s=0;s<1000;s++)
        if (VALID_SNUM(s))
          {              
-           if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),&f))
+           if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr))
              {
                printf("Allow connection from %s (%s) to %s\n",
-                      f.name,f.addr,lp_servicename(s));
+                      cname,caddr,lp_servicename(s));
              }
            else
              {
                printf("Deny connection from %s (%s) to %s\n",
-                      f.name,f.addr,lp_servicename(s));
+                      cname,caddr,lp_servicename(s));
              }
          }
     }