ipc.c: Fix for printer queue spinning with Win95.
authorJeremy Allison <jra@samba.org>
Wed, 15 Apr 1998 20:00:41 +0000 (20:00 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 15 Apr 1998 20:00:41 +0000 (20:00 +0000)
nmbd.c: Fix for always overwriting log despite append setting.
smb.h: Addition of last time password changed entry to account info.
smbpass.c: Changes to support last time changed field in smbpasswd file.
smbpasswd.c: Changes to support last time changed field in smbpasswd file.
util.c: Fix for always overwriting log despite append setting.
Jeremy.

source/include/proto.h
source/include/smb.h
source/lib/util.c
source/nmbd/nmbd.c
source/passdb/smbpass.c
source/smbd/ipc.c
source/utils/smbpasswd.c

index 07df90e1bdd006161389e297f56d0b497d4537a1..c5c7c1e846060e422de8df84d7cf5de3f80d87e0 100644 (file)
@@ -1697,6 +1697,7 @@ unsigned long getsmbpwpos(void *vp);
 BOOL setsmbpwpos(void *vp, unsigned long tok);
 struct smb_passwd *getsmbpwnam(char *name);
 struct smb_passwd *getsmbpwuid(unsigned int uid);
+char *encode_acct_ctrl(uint16 acct_ctrl);
 BOOL add_smbpwd_entry(struct smb_passwd *newpwd);
 BOOL mod_smbpwd_entry(struct smb_passwd* pwd);
 
index 95521217e982b089690dc626b2762c8c113341b1..46e282b2ba3526446151e8d30e44e574e812330a 100644 (file)
@@ -287,6 +287,7 @@ struct smb_passwd
        unsigned char *smb_nt_passwd; /* Null if no password */
        /* Other fields / flags may be added later */
         uint16 acct_ctrl;
+        time_t last_change_time;
 };
 
 struct cli_state {
index 2990a336c578ffdfffc678d8f96c161d13f00616..54bbdfa30ad283381ba99b6d8bfb8f6745bb42d7 100644 (file)
@@ -270,7 +270,10 @@ va_dcl
     {
       if (!dbf) {
              int oldumask = umask(022);
-             dbf = fopen(debugf,"w");
+              if(append_log)
+                dbf = fopen(debugf,"a");
+              else
+                dbf = fopen(debugf,"w");
              umask(oldumask);
              if (dbf) {
                      setbuf(dbf,NULL);
index 8373997e64d2b906829b3ba47009c1005878b219..5de1d3291d70c888f14d39bf5238c1699ff24c62 100644 (file)
@@ -653,6 +653,8 @@ int main(int argc,char *argv[])
         }
     }
 
+  reopen_logs();
+
   DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
   DEBUG(1,("Copyright Andrew Tridgell 1994-1997\n"));
 
index 58029a1b613e0ea23990bac4e4804a606962c6d3..e504607eb614a44992f0532c009efbdf9866a3c8 100644 (file)
@@ -192,6 +192,7 @@ struct smb_passwd *getsmbpwent(void *vp)
   }
 
   pw_buf.acct_ctrl = ACB_NORMAL;  
+  pw_buf.last_change_time = (time_t)-1;
 
   /*
    * Scan the file, a line at a time and check if the name matches.
@@ -229,14 +230,16 @@ struct smb_passwd *getsmbpwent(void *vp)
     /*
      * The line we have should be of the form :-
      * 
-     * username:uid:[32hex bytes]:....other flags presently
+     * username:uid:32hex bytes:[Account type]:LCT-12345678....other flags presently
      * ignored....
      * 
      * or,
      *
-     * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
+     * username:uid:32hex bytes:32hex bytes:[Account type]:LCT-12345678....ignored....
      *
      * if Windows NT compatible passwords are also present.
+     * [Account type] is an ascii encoding of the type of account.
+     * LCT-(8 hex digits) is the time_t value of the last change time.
      */
 
     if (linebuf[0] == '#' || linebuf[0] == '\0') {
@@ -412,6 +415,28 @@ struct smb_passwd *getsmbpwent(void *vp)
       if(pw_buf.acct_ctrl == 0)
         pw_buf.acct_ctrl = ACB_NORMAL;
 
+      /* Now try and get the last change time. */
+      if(*p == ']')
+        p++;
+      if(*p == ':') {
+        p++;
+        if(*p && StrnCaseCmp( p, "LCT-", 4)) {
+          int i;
+          p += 4;
+          for(i = 0; i < 8; i++) {
+            if(p[i] == '\0' || !isxdigit(p[i]))
+              break;
+          }
+          if(i == 8) {
+            /*
+             * p points at 8 characters of hex digits - 
+             * read into a time_t as the seconds since
+             * 1970 that the password was last changed.
+             */
+            pw_buf.last_change_time = (time_t)strtol(p, NULL, 16);
+          }
+        }
+      }
     } else {
       /* 'Old' style file. Fake up based on user name. */
       /*
@@ -519,6 +544,41 @@ struct smb_passwd *getsmbpwuid(unsigned int uid)
   return get_smbpwd_entry(NULL, uid);
 }
 
+/**********************************************************
+ Encode the account control bits into a string.
+**********************************************************/
+        
+char *encode_acct_ctrl(uint16 acct_ctrl)
+{
+  static fstring acct_str;
+  char *p = acct_str;
+  *p++ = '[';
+
+  if(acct_ctrl & ACB_HOMDIRREQ)
+    *p++ = 'H';
+  if(acct_ctrl & ACB_TEMPDUP)
+    *p++ = 'T'; 
+  if(acct_ctrl & ACB_NORMAL)
+    *p++ = 'U';
+  if(acct_ctrl & ACB_MNS)
+    *p++ = 'M';
+  if(acct_ctrl & ACB_WSTRUST)
+    *p++ = 'W';
+  if(acct_ctrl & ACB_SVRTRUST) 
+    *p++ = 'S';
+  if(acct_ctrl & ACB_AUTOLOCK)
+    *p++ = 'L';
+  if(acct_ctrl & ACB_PWNOEXP)
+    *p++ = 'X';
+  if(acct_ctrl & ACB_DOMTRUST)
+    *p++ = 'I';
+      
+  *p++ = ']';
+  *p = '\0';
+  return acct_str;
+}     
+
 /************************************************************************
  Routine to add an entry to the smbpasswd file.
 *************************************************************************/
@@ -574,7 +634,7 @@ Error was %s\n", pwd->smb_name, pfile, strerror(errno)));
     return False;
   }
 
-  new_entry_length = strlen(pwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + 2;
+  new_entry_length = strlen(pwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + 5 + 1 + 13 + 2;
 
   if((new_entry = (char *)malloc( new_entry_length )) == NULL) {
     DEBUG(0, ("add_smbpwd_entry(malloc): Failed to add entry for user %s to file %s. \
@@ -600,10 +660,13 @@ Error was %s\n", pwd->smb_name, pfile, strerror(errno)));
   p += 32;
 
   *p++ = ':';
-  sprintf((char *)p,"\n");
+
+  /* Add the account encoding and the last change time. */
+  sprintf((char *)p, "%s:LCT-%08X:\n", encode_acct_ctrl(pwd->acct_ctrl),
+                     (uint32)time(NULL));
 
 #ifdef DEBUG_PASSWORD
-  DEBUG(100, ("add_smbpwd_entry(%d): new_entry_len %d entry_len %d made line |%s|\n", 
+  DEBUG(100, ("add_smbpwd_entry(%d): new_entry_len %d entry_len %d made line |%s|", 
                             fd, new_entry_length, strlen(new_entry), new_entry));
 #endif
 
@@ -641,13 +704,15 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
   char            linebuf[256];
   char            readbuf[16 * 1024];
   unsigned char   c;
-  char            ascii_p16[66];
+  fstring         ascii_p16;
+  fstring         encode_bits;
   unsigned char  *p = NULL;
   long            linebuf_len = 0;
   FILE           *fp;
   int             lockfd;
   char           *pfile = lp_smb_passwd_file();
   BOOL found_entry = False;
+  BOOL got_last_change_time = False;
 
   long pwd_seekpos = 0;
 
@@ -837,6 +902,55 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
     return False;
   }
 
+  /* 
+   * Now check if the account info and the password last
+   * change time is available.
+   */
+  p += 33; /* Move to the first character of the line after
+              the NT password. */
+
+  if (*p == '[') {
+
+    /* 
+     * Note that here we are assuming that the account
+     * info in the pwd struct matches the account info
+     * here in the file. It better..... JRA.
+     */
+
+    i = 0;
+    p++;
+    while((linebuf_len > PTR_DIFF(p, linebuf)) && (*p != ']'))
+      encode_bits[i++] = *p++;
+
+    encode_bits[i] = '\0';
+
+    /* Go past the ']' */
+    if(linebuf_len > PTR_DIFF(p, linebuf))
+      p++;
+
+    if((linebuf_len > PTR_DIFF(p, linebuf)) && (*p == ':')) {
+      p++;
+
+      /* We should be pointing at the TLC entry. */
+      if((linebuf_len > (PTR_DIFF(p, linebuf) + 13)) && StrnCaseCmp( p, "LCT-", 4)) {
+
+        p += 4;
+        for(i = 0; i < 8; i++) {
+          if(p[i] == '\0' || !isxdigit(p[i]))
+            break;
+        }
+        if(i == 8) {
+          /*
+           * p points at 8 characters of hex digits -
+           * read into a time_t as the seconds since
+           * 1970 that the password was last changed.
+           */
+          got_last_change_time = True;
+        } /* i == 8 */
+      } /* *p && StrnCaseCmp() */
+    } /* p == ':' */
+  } /* p == '[' */
+
   /* Entry is correctly formed. */
 
   /*
@@ -889,6 +1003,17 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
     strcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
   }
 
+  /* Add on the account info bits and the time of last
+     password change. */
+
+  pwd->last_change_time = time(NULL);
+
+  if(got_last_change_time) {
+    sprintf(&ascii_p16[strlen(ascii_p16)], ":[%s]:TLC-%08X", 
+                     encode_bits, (uint32)pwd->last_change_time );
+    wr_len = strlen(ascii_p16);
+  }
+
 #ifdef DEBUG_PASSWORD
   DEBUG(100,("mod_smbpwd_entry: "));
   dump_data(100, ascii_p16, wr_len);
index e4ddcbec693a822f8f2b9fcff00bc96054d51d18..7cf4d6f5b8485df2d88d686284792faecf315184 100644 (file)
@@ -330,8 +330,9 @@ static BOOL init_package(struct pack_desc* p, int count, int subcount)
   p->subcount = 0;
   p->curpos = p->format;
   if (i > n) {
+    p->neededlen = i;
     i = n = 0;
-    p->errcode = NERR_BufTooSmall;
+    p->errcode = ERROR_MORE_DATA;
   }
   else
     p->errcode = NERR_Success;
index b569ba96b35c8411cc0cc834fc4bc585f9e3cca5..ca59ae52e928fd61e2520149cf5e861cc3afeda5 100644 (file)
@@ -106,7 +106,7 @@ static int gethexpwd(char *p, char *pwd)
 
 static struct smb_passwd *
 _my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd, 
-               BOOL *got_valid_nt_entry, long *pwd_seekpos)
+               BOOL *got_valid_nt_entry, BOOL *got_valid_last_change_time, long *pwd_seekpos)
 {
        /* Static buffers we will return. */
        static struct smb_passwd pw_buf;
@@ -121,6 +121,9 @@ _my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd,
        long            linebuf_len;
 
         pw_buf.acct_ctrl = ACB_NORMAL;
+        *got_valid_last_change_time = False;
+        *got_valid_nt_entry = False;
+        *valid_old_pwd = False;
 
        /*
         * Scan the file, a line at a time and check if the name matches.
@@ -337,7 +340,31 @@ _my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd,
                   /* Must have some account type set. */
                   if(pw_buf.acct_ctrl == 0)
                     pw_buf.acct_ctrl = ACB_NORMAL;
-            
+           
+                  /* Now try and get the last change time. */
+                  if(*p == ']')
+                    p++;
+                  if(*p == ':') {
+                      p++;
+                    if(*p && StrnCaseCmp( p, "LCT-", 4)) {
+                      int i;
+                      p += 4;
+                      for(i = 0; i < 8; i++) {
+                        if(p[i] == '\0' || !isxdigit(p[i]))
+                          break;
+                      }
+                      if(i == 8) {
+                      /*
+                       * p points at 8 characters of hex digits -
+                       * read into a time_t as the seconds since
+                       * 1970 that the password was last changed.
+                       */
+                        pw_buf.last_change_time = (time_t)strtol(p, NULL, 16);
+                        *got_valid_last_change_time = True;
+                      } /* i == 8 */
+                    } /* *p && StrnCaseCmp() */
+                  } /* *p == ':' */
                 } else {
                   /* 'Old' style file. Fake up based on user name. */
                   /*
@@ -355,41 +382,6 @@ _my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd,
        return NULL;
 }
 
-/**********************************************************
- Encode the account control bits into a string.
-**********************************************************/
-
-char *encode_acct_ctrl(uint16 acct_ctrl)
-{
-  static fstring acct_str;
-  char *p = acct_str;
-
-  *p++ = '[';
-
-  if(acct_ctrl & ACB_HOMDIRREQ)
-    *p++ = 'H';
-  if(acct_ctrl & ACB_TEMPDUP)
-    *p++ = 'T';
-  if(acct_ctrl & ACB_NORMAL)
-    *p++ = 'U';
-  if(acct_ctrl & ACB_MNS)
-    *p++ = 'M';
-  if(acct_ctrl & ACB_WSTRUST)
-    *p++ = 'W';
-  if(acct_ctrl & ACB_SVRTRUST)
-    *p++ = 'S';
-  if(acct_ctrl & ACB_AUTOLOCK)
-    *p++ = 'L';
-  if(acct_ctrl & ACB_PWNOEXP)
-    *p++ = 'X';
-  if(acct_ctrl & ACB_DOMTRUST)
-    *p++ = 'I';
-
-  *p++ = ']';
-  *p = '\0';
-  return acct_str;
-}
-
 /**********************************************************
  Allocate an unused uid in the smbpasswd file to a new
  machine account.
@@ -454,7 +446,7 @@ int main(int argc, char **argv)
   BOOL          got_valid_nt_entry = False;
   long            seekpos;
   int             pwfd;
-  char            ascii_p16[66];
+  pstring         ascii_p16;
   char            c;
   int             ch;
   int             ret, i, err, writelen;
@@ -467,6 +459,7 @@ int main(int argc, char **argv)
   char *remote_machine = NULL;
   BOOL          add_user = False;
   BOOL          got_new_pass = False;
+  BOOL          got_valid_last_change_time = False;
   BOOL          machine_account = False;
   BOOL          disable_user = False;
   BOOL          set_no_password = False;
@@ -833,7 +826,7 @@ int main(int argc, char **argv)
 
   /* Get the smb passwd entry for this user */
   smb_pwent = _my_get_smbpwnam(fp, user_name, &valid_old_pwd, 
-                              &got_valid_nt_entry, &seekpos);
+                    &got_valid_nt_entry, &got_valid_last_change_time, &seekpos);
   if (smb_pwent == NULL) {
     if(add_user == False) {
       fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
@@ -866,6 +859,7 @@ Error was %s\n", prog_name, user_name, pfile, strerror(errno));
 
       new_entry_length = strlen(user_name) + 1 + 15 + 1 + 
                          32 + 1 + 32 + 1 + sizeof(fstring) + 
+                         1 + 13 + 
                          1 + strlen(pwd->pw_dir) + 1 + 
                          strlen(pwd->pw_shell) + 1;
       if((new_entry = (char *)malloc( new_entry_length )) == 0) {
@@ -898,8 +892,8 @@ Error was %s\n", prog_name, pwd->pw_name, pfile, strerror(errno));
       }
       p += 32;
       *p++ = ':';
-      sprintf(p, "%s:%s:%s\n", encode_acct_ctrl(acct_ctrl),
-              pwd->pw_dir, pwd->pw_shell);
+      sprintf(p, "%s:TLC-%08X:%s:%s\n", encode_acct_ctrl(acct_ctrl),
+              (uint32)time(NULL), pwd->pw_dir, pwd->pw_shell);
       if(write(fd, new_entry, strlen(new_entry)) != strlen(new_entry)) {
         fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \
 Error was %s\n", prog_name, pwd->pw_name, pfile, strerror(errno));
@@ -924,7 +918,8 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
   }
 
   /*
-   * We are root - just write the new password.
+   * We are root - just write the new password
+   * and the valid last change time.
    */
 
   /* Create the 32 byte representation of the new p16 */
@@ -950,6 +945,13 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
       }
     }
   }
+  ascii_p16[65] = ':';
+  ascii_p16[66] = '\0';
+  if(got_valid_last_change_time) {
+    strcpy(&ascii_p16[66], encode_acct_ctrl(smb_pwent->acct_ctrl));
+    sprintf(&ascii_p16[strlen(ascii_p16)], ":TLC-%08X", (uint32)time(NULL));
+  }
+
   /*
    * Do an atomic write into the file at the position defined by
    * seekpos.
@@ -984,7 +986,8 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
     fclose(fp);
     exit(1);
   }
-  writelen = (got_valid_nt_entry) ? 65 : 32;
+  writelen = (got_valid_nt_entry) ? 
+              ( got_valid_last_change_time ? strlen(ascii_p16) : 65) : 32;
   if (write(pwfd, ascii_p16, writelen) != writelen) {
     err = errno;
     fprintf(stderr, "%s: write fail in file %s.\n",