- changed smb_getpwnam() to use winbind style usernames
[kai/samba.git] / source / smbd / reply.c
index a020f5eb3b12189e1f30a56b45886f5199ea0ed0..1fc377f36220d5ed704f85150142269df01647e2 100644 (file)
@@ -1,3 +1,4 @@
+#define OLD_NTDOMAIN 1
 /* 
    Unix SMB/Netbios implementation.
    Version 1.9.
@@ -25,8 +26,6 @@
 
 
 #include "includes.h"
-#include "trans2.h"
-#include "nterr.h"
 
 /* look in server.c for some explanation of these variables */
 extern int Protocol;
@@ -500,6 +499,7 @@ static int smb_create_user(char *unix_user)
   int ret;
 
   pstrcpy(add_script, lp_adduser_script());
+  if (! *add_script) return -1;
   pstring_sub(add_script, "%u", unix_user);
   ret = smbrun(add_script,NULL,False);
   DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
@@ -516,6 +516,7 @@ static int smb_delete_user(char *unix_user)
   int ret;
 
   pstrcpy(del_script, lp_deluser_script());
+  if (! *del_script) return -1;
   pstring_sub(del_script, "%u", unix_user);
   ret = smbrun(del_script,NULL,False);
   DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
@@ -571,7 +572,7 @@ static BOOL check_server_security(char *orig_user, char *domain, char *unix_user
      * level security as we never know if it was a failure
      * due to a bad password, or the user really doesn't exist.
      */
-    if(lp_adduser_script() && !Get_Pwnam(unix_user,True)) {
+    if(lp_adduser_script() && !smb_getpwnam(unix_user,True)) {
       smb_create_user(unix_user);
     }
   }
@@ -607,7 +608,7 @@ static BOOL check_domain_security(char *orig_user, char *domain, char *unix_user
      * If the admin wants us to try and create a UNIX
      * user on the fly, do so.
      */
-    if(user_exists && lp_adduser_script() && !Get_Pwnam(unix_user,True)) {
+    if(user_exists && lp_adduser_script() && !smb_getpwnam(unix_user,True)) {
       smb_create_user(unix_user);
     }
   } else {
@@ -617,7 +618,7 @@ static BOOL check_domain_security(char *orig_user, char *domain, char *unix_user
      * wants us to try and delete that UNIX user on the fly,
      * do so.
      */
-    if(!user_exists && lp_deluser_script() && Get_Pwnam(unix_user,True)) {
+    if(!user_exists && lp_deluser_script() && smb_getpwnam(unix_user,True)) {
       smb_delete_user(unix_user);
     }
   }
@@ -840,14 +841,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
 
   strlower(user);
 
-  /*
-   * In share level security, only overwrite sesssetup_use if
-   * it's a non null-session share. Helps keep %U and %G
-   * working.
-   */
-
-  if((lp_security() != SEC_SHARE) || (*user && !guest))
-    pstrcpy(sesssetup_user,user);
+  pstrcpy(sesssetup_user,user);
 
   reload_services(True);
 
@@ -859,6 +853,17 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
 
   pstrcpy( orig_user, user);
 
+  /* if the username exists as a domain/username pair on the unix system then use 
+     that */
+  if (!Get_Pwnam(user, False)) {
+         pstring user2;
+         slprintf(user2,sizeof(user2),"%s/%s", domain, user);
+         if (Get_Pwnam(user2, True)) {
+                 DEBUG(3,("Using unix username %s\n", user2));
+                 pstrcpy(user, user2);
+         }
+  }
+
   /*
    * Pass the user through the NT -> unix user mapping
    * function.
@@ -869,7 +874,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
   /*
    * Do any UNIX username case mangling.
    */
-  (void)Get_Pwnam( user, True);
+  smb_getpwnam(user, True);
 
   add_session_user(user);
 
@@ -926,7 +931,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
 
         if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER)
         {
-          if (Get_Pwnam(user,True))
+          if (smb_getpwnam(user,True))
           {
             DEBUG(1,("Rejecting user '%s': bad password\n", user));
             return bad_password_error(inbuf,outbuf);
@@ -939,15 +944,15 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
          */
       }
 
-      if (*smb_apasswd || !Get_Pwnam(user,True))
+      if (*smb_apasswd || !smb_getpwnam(user,True))
          pstrcpy(user,lp_guestaccount(-1));
       DEBUG(3,("Registered username %s for guest access\n",user));
       guest = True;
     }
   }
 
-  if (!Get_Pwnam(user,True)) {
-    DEBUG(3,("No such user %s - using guest account\n",user));
+  if (!smb_getpwnam(user,True)) {
+    DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
     pstrcpy(user,lp_guestaccount(-1));
     guest = True;
   }
@@ -981,7 +986,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
      user we should become.
      */
   {
-    const struct passwd *pw = Get_Pwnam(user,False);
+    const struct passwd *pw = smb_getpwnam(user,False);
     if (!pw) {
       DEBUG(1,("Username %s is invalid on this system\n",user));
       return bad_password_error(inbuf,outbuf);
@@ -995,7 +1000,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
 
   /* register the name and uid as being validated, so further connections
      to a uid can get through without a password, on the same VC */
-  sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest);
+  sess_vuid = register_vuid(uid,gid,user,sesssetup_user,domain,guest);
  
   SSVAL(outbuf,smb_uid,sess_vuid);
   SSVAL(inbuf,smb_uid,sess_vuid);
@@ -1267,9 +1272,6 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   
   /* dirtype &= ~aDIR; */
   
-  DEBUG(5,("reply_search: path=%s status_len=%d\n",path,status_len));
-
-  
   if (status_len == 0)
   {
     pstring dir2;
@@ -1308,66 +1310,14 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   else
   {
     memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
-    memcpy(mask,status+1,11);
-    mask[11] = 0;
     dirtype = CVAL(status,0) & 0x1F;
     conn->dirptr = dptr_fetch(status+12,&dptr_num);      
     if (!conn->dirptr)
       goto SearchEmpty;
     string_set(&conn->dirpath,dptr_path(dptr_num));
-    if (!case_sensitive)
-      strnorm(mask);
+    fstrcpy(mask, dptr_wcard(dptr_num));
   }
 
-  /* turn strings of spaces into a . */  
-  {
-    trim_string(mask,NULL," ");
-    if ((p = strrchr(mask,' ')))
-    {
-      fstring ext;
-      fstrcpy(ext,p+1);
-      *p = 0;
-      trim_string(mask,NULL," ");
-      pstrcat(mask,".");
-      pstrcat(mask,ext);
-    }
-  }
-
-  /* Convert the formatted mask. (This code lives in trans2.c) */
-  mask_convert(mask);
-
-  {
-    int skip;
-    p = mask;
-    while(*p)
-    {
-      if((skip = get_character_len( *p )) != 0 )
-      {
-        p += skip;
-      }
-      else
-      {
-        if (*p != '?' && *p != '*' && !isdoschar(*p))
-        {
-          DEBUG(5,("Invalid char [%c] in search mask?\n",*p));
-          *p = '?';
-        }
-        p++;
-      }
-    }
-  }
-
-  if (!strchr(mask,'.') && strlen(mask)>8)
-  {
-    fstring tmp;
-    fstrcpy(tmp,&mask[8]);
-    mask[8] = '.';
-    mask[9] = 0;
-    pstrcat(mask,tmp);
-  }
-
-  DEBUG(5,("mask=%s directory=%s\n",mask,directory));
-  
   if (can_open)
   {
     p = smb_buf(outbuf) + 3;
@@ -1390,6 +1340,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
         }
         return(ERROR(ERRDOS,ERRnofids));
       }
+      dptr_set_wcard(dptr_num, strdup(mask));
     }
 
     DEBUG(4,("dptr_num is %d\n",dptr_num));
@@ -1424,8 +1375,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
             make_dir_struct(p,mask,fname,size,mode,date);
             dptr_fill(p+12,dptr_num);
             numentries++;
-          }
-          p += DIR_STRUCT_SIZE;
+         }
+         p += DIR_STRUCT_SIZE;
         }
       }
        } /* if (ok ) */
@@ -1938,7 +1889,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   if (!rc && is_mangled(mask))
     check_mangled_cache( mask );
 
-  has_wild = strchr(mask,'*') || strchr(mask,'?');
+  has_wild = ms_has_wild(mask);
 
   if (!has_wild) {
     pstrcat(directory,"/");
@@ -1971,7 +1922,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
            pstring fname;
            pstrcpy(fname,dname);
            
-           if(!mask_match(fname, mask, case_sensitive, False)) continue;
+           if(!mask_match(fname, mask, case_sensitive)) continue;
 
            error = ERRnoaccess;
            slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
@@ -2413,7 +2364,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
 
   if ((lp_syncalways(SNUM(conn)) || write_through) && 
       lp_strict_sync(SNUM(conn)))
-      conn->vfs_ops.fsync(fsp->fd);
+      sync_file(conn,fsp);
 
   DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
           fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
@@ -2461,7 +2412,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
     nwritten = write_file(fsp,data,startpos,numtowrite);
   
   if (lp_syncalways(SNUM(conn)))
-      conn->vfs_ops.fsync(fsp->fd);
+      sync_file(conn,fsp);
 
   if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2516,7 +2467,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
     nwritten = write_file(fsp,data,startpos,numtowrite);
   
   if (lp_syncalways(SNUM(conn)))
-    conn->vfs_ops.fsync(fsp->fd);
+    sync_file(conn,fsp);
 
   if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2547,7 +2498,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   size_t numtowrite = SVAL(inbuf,smb_vwv10);
   BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
   ssize_t nwritten = -1;
-  int smb_doff = SVAL(inbuf,smb_vwv11);
+  unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
   char *data;
 
   /* If it's an IPC, pass off the pipe handler. */
@@ -2558,6 +2509,9 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   CHECK_WRITE(fsp);
   CHECK_ERROR(fsp);
 
+  if(smb_doff > smb_len(inbuf))
+    return(ERROR(ERRDOS,ERRbadmem));
+
   data = smb_base(inbuf) + smb_doff;
 
   if(CVAL(inbuf,smb_wct) == 14) {
@@ -2610,7 +2564,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
           fsp->fnum, (int)numtowrite, (int)nwritten));
 
   if (lp_syncalways(SNUM(conn)) || write_through)
-    conn->vfs_ops.fsync(fsp->fd);
+    sync_file(conn,fsp);
 
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
@@ -2707,7 +2661,7 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int
   if (!fsp) {
          file_sync_all(conn);
   } else {
-         conn->vfs_ops.fsync(fsp->fd);
+               sync_file(conn,fsp);
   }
 
   DEBUG(3,("flush\n"));
@@ -2962,9 +2916,11 @@ int reply_echo(connection_struct *conn,
 {
        int smb_reverb = SVAL(inbuf,smb_vwv0);
        int seq_num;
-       int data_len = smb_buflen(inbuf);
+       unsigned int data_len = smb_buflen(inbuf);
        int outsize = set_message(outbuf,1,data_len,True);
-       
+
+       data_len = MIN(data_len, (sizeof(inbuf)-(smb_buf(inbuf)-inbuf)));
+
        /* copy any incoming data back out */
        if (data_len > 0)
                memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
@@ -3505,7 +3461,7 @@ int rename_internals(connection_struct *conn,
        if (!rc && is_mangled(mask))
                check_mangled_cache( mask );
 
-       has_wild = strchr(mask,'*') || strchr(mask,'?');
+       has_wild = ms_has_wild(mask);
 
        if (!has_wild) {
                /*
@@ -3615,7 +3571,7 @@ int rename_internals(connection_struct *conn,
 
                                pstrcpy(fname,dname);
                                
-                               if(!mask_match(fname, mask, case_sensitive, False))
+                               if(!mask_match(fname, mask, case_sensitive))
                                        continue;
                                
                                error = ERRnoaccess;
@@ -3844,7 +3800,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   if (!rc && is_mangled(mask))
     check_mangled_cache( mask );
 
-  has_wild = strchr(mask,'*') || strchr(mask,'?');
+  has_wild = ms_has_wild(mask);
 
   if (!has_wild) {
     pstrcat(directory,"/");
@@ -3875,7 +3831,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
            pstring fname;
            pstrcpy(fname,dname);
            
-           if(!mask_match(fname, mask, case_sensitive, False))
+           if(!mask_match(fname, mask, case_sensitive))
                        continue;
 
            error = ERRnoaccess;
@@ -4302,7 +4258,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
   nwritten = write_file(fsp,data,startpos,numtowrite);
 
   if(lp_syncalways(SNUM(conn)) || write_through)
-      conn->vfs_ops.fsync(fsp->fd);
+      sync_file(conn,fsp);
   
   if(nwritten < (ssize_t)numtowrite)
     return(UNIXERROR(ERRHRD,ERRdiskfull));
@@ -4403,7 +4359,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
   nwritten = write_file(fsp,data,startpos,numtowrite);
 
   if(lp_syncalways(SNUM(conn)) || write_through)
-    conn->vfs_ops.fsync(fsp->fd);
+    sync_file(conn,fsp);
   
   if (nwritten < (ssize_t)numtowrite)
   {
@@ -4537,3 +4493,4 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
   
   return(outsize);
 }
+#undef OLD_NTDOMAIN