mods to allow inter-domain trust accounts to be added to SAM database
authorLuke Leighton <lkcl@samba.org>
Tue, 9 Mar 1999 01:21:57 +0000 (01:21 +0000)
committerLuke Leighton <lkcl@samba.org>
Tue, 9 Mar 1999 01:21:57 +0000 (01:21 +0000)
using smbpasswd command.
(This used to be commit 62d499f83256c6e8b3308dc4bd8e9f5df873b14b)

source3/include/proto.h
source3/lib/util.c
source3/nmbd/nmbd_packets.c
source3/passdb/smbpass.c
source3/passdb/smbpasschange.c
source3/utils/smbpasswd.c
source3/web/swat.c

index bf280df1cd62d0e37ddc0a0eb08ade8f22fd58e0..6d2264051fd0a4125c4cd56eda4cc8b3e61e56a7 100644 (file)
@@ -1529,11 +1529,12 @@ struct smb_passdb_ops *file_initialise_password_db(void);
 
 /*The following definitions come from  passdb/smbpasschange.c  */
 
-BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
-                          BOOL enable_user, BOOL disable_user, BOOL set_no_password,
-                          char *new_passwd, 
-                          char *err_str, size_t err_str_len,
-                          char *msg_str, size_t msg_str_len);
+BOOL local_password_change(char *user_name,
+                               BOOL add_user,
+                               uint16 acb_info, uint16 acb_mask,
+                               char *new_passwd, 
+                               char *err_str, size_t err_str_len,
+                               char *msg_str, size_t msg_str_len);
 
 /*The following definitions come from  passdb/smbpassfile.c  */
 
index 127f69dc7d65c64b774371671d1b715a095a8837..2bab2f0386e9c887b599b718dd0243d73ec309fe 100644 (file)
@@ -2975,40 +2975,46 @@ void print_asc(int level, unsigned char *buf,int len)
 {
        int i;
        for (i=0;i<len;i++)
-               DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
+       {
+               DEBUGADD(level,("%c", isprint(buf[i])?buf[i]:'.'));
+       }
 }
 
-void dump_data(int level,char *buf1,int len)
+void dump_data(int level,char *buf1, int len)
 {
-  unsigned char *buf = (unsigned char *)buf1;
-  int i=0;
-  if (len<=0) return;
+       unsigned char *buf = (unsigned char *)buf1;
+       int i=0;
+       if (len<=0) return;
 
-  DEBUG(level,("[%03X] ",i));
-  for (i=0;i<len;) {
-    DEBUG(level,("%02X ",(int)buf[i]));
-    i++;
-    if (i%8 == 0) DEBUG(level,(" "));
-    if (i%16 == 0) {      
-      print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
-      print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
-      if (i<len) DEBUG(level,("[%03X] ",i));
-    }
-  }
-  if (i%16) {
-    int n;
-
-    n = 16 - (i%16);
-    DEBUG(level,(" "));
-    if (n>8) DEBUG(level,(" "));
-    while (n--) DEBUG(level,("   "));
-
-    n = MIN(8,i%16);
-    print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
-    n = (i%16) - n;
-    if (n>0) print_asc(level,&buf[i-n],n); 
-    DEBUG(level,("\n"));    
-  }
+       DEBUG(level,("[%03X] ",i));
+       for (i=0;i<len;)
+       {
+               DEBUGADD(level,("%02X ",(int)buf[i]));
+               i++;
+               if (i%8 == 0) DEBUGADD(level,(" "));
+               if (i%16 == 0)
+               {      
+                       print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
+                       print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
+                       if (i<len) DEBUGADD(level,("[%03X] ",i));
+               }
+       }
+
+       if (i%16 != 0) /* finish off a non-16-char-length row */
+       {
+               int n;
+
+               n = 16 - (i%16);
+               DEBUGADD(level,(" "));
+               if (n>8) DEBUGADD(level,(" "));
+               while (n--) DEBUGADD(level,("   "));
+
+               n = MIN(8,i%16);
+               print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,(" "));
+               n = (i%16) - n;
+               if (n>0) print_asc(level,&buf[i-n],n); 
+               DEBUGADD(level,("\n"));    
+       }
 }
 
 char *tab_depth(int depth)
index 7f277533522e119114b3051c92b6a9cd00cb6ae1..a9803b363f1837a6190a24a5230f58124200ca8e 100644 (file)
@@ -90,43 +90,6 @@ void set_nb_flags(char *buf, uint16 nb_flags)
   *buf = '\0';
 }
 
-/***************************************************************************
-Dumps out the browse packet data.
-**************************************************************************/
-
-static void debug_browse_data(char *outbuf, int len)
-{
-  int i,j;
-
-  DEBUG( 4, ( "debug_browse_data():\n" ) );
-  for (i = 0; i < len; i+= 16)
-  {
-    DEBUGADD( 4, ( "%3x char ", i ) );
-
-    for (j = 0; j < 16; j++)
-    {
-      unsigned char x = outbuf[i+j];
-      if (x < 32 || x > 127) 
-        x = '.';
-           
-      if (i+j >= len)
-        break;
-      DEBUGADD( 4, ( "%c", x ) );
-    }
-
-    DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
-
-    for (j = 0; j < 16; j++)
-    {
-      if (i+j >= len) 
-        break;
-      DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
-    }
-
-    DEBUGADD( 4, ("\n") );
-  }
-}
-
 /***************************************************************************
   Generates the unique transaction identifier
 **************************************************************************/
@@ -1041,37 +1004,31 @@ mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, scop
   {
     case ANN_HostAnnouncement:
     {
-      debug_browse_data(buf, len);
       process_host_announce(subrec, p, buf+1);
       break;
     }
     case ANN_DomainAnnouncement:
     {
-      debug_browse_data(buf, len);
       process_workgroup_announce(subrec, p, buf+1);
       break;
     }
     case ANN_LocalMasterAnnouncement:
     {
-      debug_browse_data(buf, len);
       process_local_master_announce(subrec, p, buf+1);
       break;
     }
     case ANN_AnnouncementRequest:
     {
-      debug_browse_data(buf, len);
       process_announce_request(subrec, p, buf+1);
       break;
     }
     case ANN_Election:
     {
-      debug_browse_data(buf, len);
       process_election(subrec, p, buf+1);
       break;
     }
     case ANN_GetBackupListReq:
     {
-      debug_browse_data(buf, len);
 
       /* This is one occasion where we change a subnet that is
         given to us. If the packet was sent to WORKGROUP<1b> instead
@@ -1086,7 +1043,6 @@ mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, scop
     }
     case ANN_GetBackupListResp:
     {
-      debug_browse_data(buf, len);
       /* We never send ANN_GetBackupListReq so we
          should never get these. */
       DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
@@ -1095,7 +1051,6 @@ packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
     }
     case ANN_ResetBrowserState:
     {
-      debug_browse_data(buf, len);
       process_reset_browser(subrec, p, buf+1);
       break;
     }
@@ -1105,7 +1060,6 @@ packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
          on the unicast subnet. */
       subrec = unicast_subnet;
 
-      debug_browse_data(buf, len);
       process_master_browser_announce(subrec, p, buf+1);
       break;
     }
@@ -1114,7 +1068,6 @@ packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
       /* 
        * We don't currently implement this. Log it just in case.
        */
-      debug_browse_data(buf, len);
       DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
 command ANN_BecomeBackup from %s IP %s to %s\n",
             subrec->subnet_name, nmb_namestr(&dgram->source_name),
@@ -1123,7 +1076,6 @@ command ANN_BecomeBackup from %s IP %s to %s\n",
     }
     default:
     {
-      debug_browse_data(buf, len);
       DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
 command code %d from %s IP %s to %s\n", 
             subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
@@ -1162,7 +1114,7 @@ mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, scop
   {
     case ANN_HostAnnouncement:
     {
-      debug_browse_data(buf, len);
+      dump_data(4, buf, len);
       process_lm_host_announce(subrec, p, buf+1);
       break;
     }
@@ -1247,10 +1199,11 @@ static void process_dgram(struct packet_struct *p)
           nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
           inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
 
   if (len <= 0)
     return;
 
+  dump_data(100, buf2, len);
   /* Datagram packet received for the browser mailslot */
   if (strequal(smb_buf(buf),BROWSE_MAILSLOT))
   {
@@ -1958,7 +1911,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
                     nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
   DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
 
-  debug_browse_data(buf, len);
+  dump_data(4, buf, len);
 
   if(loopback_this_packet)
   {
index 2686f1d68fc47e1db662733e82a356f79ed7976c..2985af1ff80ad0d928a832b40a997038be4c0805 100644 (file)
@@ -139,16 +139,6 @@ struct smb_passwd *getsmbfilepwent(void *vp)
                /* Skip the ':' */
                p++;
 
-               if (*p == '*' || *p == 'X')
-               {
-                       /* Password deliberately invalid - end here. */
-                       DEBUG(10, ("getsmbfilepwent: entry invalidated for unix user %s\n", unix_name));
-                       pw_buf.smb_nt_passwd = NULL;
-                       pw_buf.smb_passwd = NULL;
-                       pw_buf.acct_ctrl |= ACB_DISABLED;
-                       return &pw_buf;
-               }
-
                if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
                {
                        DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n"));
@@ -240,6 +230,18 @@ struct smb_passwd *getsmbfilepwent(void *vp)
                        }
                }
 
+               if (*p == '*' || *p == 'X')
+               {
+                       /* Password deliberately invalid - end here. */
+                       DEBUG(10, ("getsmbfilepwent: entry invalidated for unix user %s\n", unix_name));
+                       pw_buf.smb_nt_passwd = NULL;
+                       pw_buf.smb_passwd = NULL;
+                       pw_buf.acct_ctrl |= ACB_DISABLED;
+               }
+
+               DEBUG(6,("unixuser:%s uid:%d acb:%x\n",
+                         pw_buf.unix_name, pw_buf.unix_uid, pw_buf.acct_ctrl));
+
                return &pw_buf;
        }
 
@@ -410,8 +412,14 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100,("mod_smbfilepwd_entry: password entries\n"));
-       dump_data(100, pwd->smb_passwd, 16);
-       dump_data(100, pwd->smb_nt_passwd, 16);
+       if (pwd->smb_passwd != NULL)
+       {
+               dump_data(100, pwd->smb_passwd, 16);
+       }
+       if (pwd->smb_nt_passwd != NULL)
+       {
+               dump_data(100, pwd->smb_nt_passwd, 16);
+       }
 #endif
   if (!*pfile) {
     DEBUG(0, ("No SMB password file set\n"));
index f001040682a429fcf11c44297083bf30be8701fb..27bb26e0b32f009270f49b1af11b14096007c0ea 100644 (file)
@@ -25,9 +25,9 @@
 /*************************************************************
 add a new user to the local smbpasswd file
 *************************************************************/
-static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account, 
-                        BOOL disable_user, BOOL set_no_password,
-                        uchar *new_p16, uchar *new_nt_p16)
+static BOOL add_new_user(char *user_name, uid_t uid,
+                               uint16 acb_info,
+                               uchar *new_p16, uchar *new_nt_p16)
 {
        struct smb_passwd new_smb_pwent;
 
@@ -38,13 +38,10 @@ static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account,
        new_smb_pwent.nt_name = user_name; 
        new_smb_pwent.smb_passwd = NULL;
        new_smb_pwent.smb_nt_passwd = NULL;
-       new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL);
+       new_smb_pwent.acct_ctrl = acb_info;
        
-       if(disable_user) {
-               new_smb_pwent.acct_ctrl |= ACB_DISABLED;
-       } else if (set_no_password) {
-               new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
-       } else {
+       if (IS_BITS_CLR_ALL(acb_info, ACB_DISABLED | ACB_PWNOTREQ))
+       {
                new_smb_pwent.smb_passwd = new_p16;
                new_smb_pwent.smb_nt_passwd = new_nt_p16;
        }
@@ -54,16 +51,27 @@ static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account,
 
 
 /*************************************************************
-change a password entry in the local smbpasswd file
+change a password entry in the local smbpasswd file.
+
+when modifying an account, set acb_mask to those bits that
+require changing (to zero or one) and set acb_info to the
+value required in those bits.  all bits NOT set in acb_mask
+will NOT be modified.
+
+when _adding_ an account, acb_mask must be set to 0xFFFF and
+it is ignored, btw :-)
+
 *************************************************************/
-BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
-                          BOOL enable_user, BOOL disable_user, BOOL set_no_password,
-                          char *new_passwd, 
-                          char *err_str, size_t err_str_len,
-                          char *msg_str, size_t msg_str_len)
+BOOL local_password_change(char *user_name,
+                               BOOL add_user,
+                               uint16 acb_info, uint16 acb_mask,
+                               char *new_passwd, 
+                               char *err_str, size_t err_str_len,
+                               char *msg_str, size_t msg_str_len)
 {
        struct passwd  *pwd;
        struct smb_passwd *smb_pwent;
+       struct smb_passwd new_pwent;
        uchar           new_p16[16];
        uchar           new_nt_p16[16];
        fstring unix_name;
@@ -75,16 +83,21 @@ BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
        pwd = getpwnam(user_name);
        
        /*
-        * Check for a machine account.
+        * Check for a trust account.
         */
        
+       if ((acb_info & acb_mask) != acb_info)
+       {
+               slprintf(err_str, err_str_len - 1, "programmer error: acb_info (%x) requests bits to be set outside of acb_mask (%x) range\n", acb_info, acb_mask);
+       }
+
        if (pwd == NULL)
        {
-               if (trust_account)
+               if (!IS_BITS_SET_ALL(acb_info, ACB_NORMAL))
                {
                        slprintf(err_str, err_str_len - 1, "User %s does not \
 exist in system password file (usually /etc/passwd).  \
-Cannot add machine account without a valid system user.\n", user_name);
+Cannot add trust account without a valid system user.\n", user_name);
                }
                else
                {
@@ -102,22 +115,29 @@ exist in system password file (usually /etc/passwd).\n", user_name);
 
        /* Get the smb passwd entry for this user */
        smb_pwent = getsmbpwnam(user_name);
-       if (smb_pwent == NULL) {
-               if(add_user == False) {
+       if (smb_pwent == NULL)
+       {
+               if (!add_user)
+               {
                        slprintf(err_str, err_str_len-1,
                                "Failed to find entry for user %s.\n", unix_name);
                        return False;
                }
 
-               if (add_new_user(user_name, unix_uid, trust_account, disable_user,
-                                set_no_password, new_p16, new_nt_p16)) {
+               if (add_new_user(user_name, unix_uid, acb_info,
+                                new_p16, new_nt_p16))
+               {
                        slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
                        return True;
-               } else {
+               }
+               else
+               {
                        slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
                        return False;
                }
-       } else {
+       }
+       else
+       {
                /* the entry already existed */
                add_user = False;
        }
@@ -127,26 +147,21 @@ exist in system password file (usually /etc/passwd).\n", user_name);
         * and the valid last change time.
         */
 
-       if(disable_user) {
-               smb_pwent->acct_ctrl |= ACB_DISABLED;
-       } else if (enable_user) {
-               if(smb_pwent->smb_passwd == NULL) {
-                       smb_pwent->smb_passwd = new_p16;
-                       smb_pwent->smb_nt_passwd = new_nt_p16;
-               }
-               smb_pwent->acct_ctrl &= ~ACB_DISABLED;
-       } else if (set_no_password) {
-               smb_pwent->acct_ctrl |= ACB_PWNOTREQ;
-               /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
-               smb_pwent->smb_passwd = NULL;
-               smb_pwent->smb_nt_passwd = NULL;
-       } else {
-               smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ;
-               smb_pwent->smb_passwd = new_p16;
-               smb_pwent->smb_nt_passwd = new_nt_p16;
+       memcpy(&new_pwent, smb_pwent, sizeof(new_pwent));
+       new_pwent.nt_name = user_name; 
+       new_pwent.acct_ctrl &= ~acb_mask;
+       new_pwent.acct_ctrl |= (acb_info & acb_mask);
+       new_pwent.smb_passwd = NULL;
+       new_pwent.smb_nt_passwd = NULL;
+
+       if (IS_BITS_CLR_ALL(acb_info, ACB_DISABLED | ACB_PWNOTREQ))
+       {
+               new_pwent.smb_passwd = new_p16;
+               new_pwent.smb_nt_passwd = new_nt_p16;
        }
        
-       if(mod_smbpwd_entry(smb_pwent,True) == False) {
+       if (!mod_smbpwd_entry(&new_pwent, True))
+       {
                slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n",
                        unix_name);
                return False;
index 157583925b4af98d199c72842498088df0aaa058..83b9b0bdc9c3aae4aa6adf376fc7b84ddabff42c 100644 (file)
@@ -1,6 +1,7 @@
 /*
- * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module. Copyright
- * (C) Jeremy Allison 1995-1998
+ * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module.
+ * Copyright (C) Jeremy Allison               1995-1999
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999
  * 
  * This program is free software; you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free
@@ -67,7 +68,8 @@ static void usage(void)
                printf("  -d                   disable user\n");
                printf("  -e                   enable user\n");
                printf("  -n                   set no password\n");
-               printf("  -m                   machine trust account\n");
+               printf("  -m                   workstation trust account\n");
+               printf("  -i                   inter-domain trust account\n");
        }
        exit(1);
 }
@@ -221,35 +223,47 @@ static char *prompt_for_new_password(BOOL stdin_get)
 change a password either locally or remotely
 *************************************************************/
 static BOOL password_change(const char *remote_machine, char *user_name, 
-                           char *old_passwd, char *new_passwd, 
-                           BOOL add_user, BOOL enable_user, 
-                           BOOL disable_user, BOOL set_no_password,
-                           BOOL trust_account)
+                               char *old_passwd, char *new_passwd, 
+                               BOOL add_user, 
+                               uint16 acb_info, uint16 acb_mask)
 {
        BOOL ret;
        pstring err_str;
        pstring msg_str;
 
-       if (remote_machine != NULL) {
-               if (add_user || enable_user || disable_user || set_no_password || trust_account) {
+       if (remote_machine != NULL)
+       {
+               if (add_user ||
+                   IS_BITS_SET_SOME(acb_info, ACB_PWNOTREQ | ACB_WSTRUST | ACB_DOMTRUST | ACB_SVRTRUST) ||
+                   (IS_BITS_SET_SOME(acb_mask, ACB_DISABLED) && 
+                    IS_BITS_CLR_ALL(acb_info, ACB_DISABLED)))
+               {
                        /* these things can't be done remotely yet */
                        return False;
                }
                ret = remote_password_change(remote_machine, user_name, 
-                                                                        old_passwd, new_passwd, err_str, sizeof(err_str));
-               if(*err_str)
+                                           old_passwd, new_passwd,
+                                           err_str, sizeof(err_str));
+               if (*err_str != 0)
+               {
                        fprintf(stderr, err_str);
+               }
                return ret;
        }
        
-       ret = local_password_change(user_name, trust_account, add_user, enable_user, 
-                                    disable_user, set_no_password, new_passwd, 
-                                    err_str, sizeof(err_str), msg_str, sizeof(msg_str));
+       ret = local_password_change(user_name, add_user, acb_info, acb_mask,
+                                    new_passwd, 
+                                    err_str, sizeof(err_str),
+                                    msg_str, sizeof(msg_str));
 
-       if(*msg_str)
+       if (*msg_str != 0)
+       {
                printf(msg_str);
-       if(*err_str)
+       }
+       if (*err_str != 0)
+       {
                fprintf(stderr, err_str);
+       }
 
        return ret;
 }
@@ -262,8 +276,11 @@ static int process_root(int argc, char *argv[])
 {
        struct passwd  *pwd;
        int ch;
+       uint16 acb_info = 0;
+       uint16 acb_mask = 0;
        BOOL joining_domain = False;
-       BOOL trust_account = False;
+       BOOL wks_trust_account = False;
+       BOOL dom_trust_account = False;
        BOOL add_user = False;
        BOOL disable_user = False;
        BOOL enable_user = False;
@@ -275,65 +292,97 @@ static int process_root(int argc, char *argv[])
        char *old_passwd = NULL;
        char *remote_machine = NULL;
 
-       while ((ch = getopt(argc, argv, "adehmnj:r:sR:D:U:")) != EOF) {
-               switch(ch) {
-               case 'a':
-                       add_user = True;
-                       break;
-               case 'd':
-                       disable_user = True;
-                       new_passwd = "XXXXXX";
-                       break;
-               case 'e':
-                       enable_user = True;
-                       break;
-               case 'D':
-                       DEBUGLEVEL = atoi(optarg);
-                       break;
-               case 'n':
-                       set_no_password = True;
-                       new_passwd = "NO PASSWORD";
-               case 'r':
-                       remote_machine = optarg;
-                       break;
-               case 's':
-                       set_line_buffering(stdin);
-                       set_line_buffering(stdout);
-                       set_line_buffering(stderr);
-                       stdin_passwd_get = True;
-                       break;
-               case 'R':
-                       lp_set_name_resolve_order(optarg);
-                       break;
-               case 'm':
-                       trust_account = True;
-                       break;
-               case 'j':
-                       new_domain = optarg;
-                       strupper(new_domain);
-                       joining_domain = True;
-                       break;
-               case 'U':
-                       user_name = optarg;
-                       break;
-               default:
-                       usage();
+       while ((ch = getopt(argc, argv, "adehimnj:r:sR:D:U:")) != EOF)
+       {
+               switch(ch)
+               {
+                       case 'a':
+                       {
+                               add_user = True;
+                               break;
+                       }
+                       case 'd':
+                       {
+                               disable_user = True;
+                               new_passwd = "XXXXXX";
+                               break;
+                       }
+                       case 'e':
+                       {
+                               enable_user = True;
+                               break;
+                       }
+                       case 'D':
+                       {
+                               DEBUGLEVEL = atoi(optarg);
+                               break;
+                       }
+                       case 'n':
+                       {
+                               set_no_password = True;
+                               new_passwd = "NO PASSWORD";
+                       }
+                       case 'r':
+                       {
+                               remote_machine = optarg;
+                               break;
+                       }
+                       case 's':
+                       {
+                               set_line_buffering(stdin);
+                               set_line_buffering(stdout);
+                               set_line_buffering(stderr);
+                               stdin_passwd_get = True;
+                               break;
+                       }
+                       case 'R':
+                       {
+                               lp_set_name_resolve_order(optarg);
+                               break;
+                       }
+                       case 'i':
+                       {
+                               dom_trust_account = True;
+                               break;
+                       }
+                       case 'm':
+                       {
+                               wks_trust_account = True;
+                               break;
+                       }
+                       case 'j':
+                       {
+                               new_domain = optarg;
+                               strupper(new_domain);
+                               joining_domain = True;
+                               break;
+                       }
+                       case 'U':
+                       {
+                               user_name = optarg;
+                               break;
+                       }
+                       default:
+                       {
+                               usage();
+                       }
                }
        }
        
        argc -= optind;
        argv += optind;
 
-
        /*
         * Ensure add_user and either remote machine or join domain are
         * not both set.
         */     
-       if(add_user && ((remote_machine != NULL) || joining_domain)) {
+       if (add_user && ((remote_machine != NULL) || joining_domain))
+       {
                usage();
        }
        
-       if(joining_domain) {
+       if (joining_domain)
+       {
                if (argc != 0) usage();
                return join_domain(new_domain, remote_machine);
        }
@@ -365,7 +414,8 @@ static int process_root(int argc, char *argv[])
                exit(1);
        }
 
-       if (trust_account) {
+       if (wks_trust_account || dom_trust_account)
+       {
                /* add the $ automatically */
                static fstring buf;
 
@@ -402,7 +452,8 @@ static int process_root(int argc, char *argv[])
                old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
        }
        
-       if (!new_passwd) {
+       if (!new_passwd)
+       {
 
                /*
                 * If we are trying to enable a user, first we need to find out
@@ -413,31 +464,76 @@ static int process_root(int argc, char *argv[])
                 * smbpasswd file) then we need to prompt for a new password.
                 */
 
-               if(enable_user) {
+               if (enable_user)
+               {
                        struct smb_passwd *smb_pass = getsmbpwnam(user_name);
-                       if((smb_pass != NULL) && (smb_pass->smb_passwd != NULL)) {
+                       if((smb_pass != NULL) && (smb_pass->smb_passwd != NULL))
+                       {
                                new_passwd = "XXXX"; /* Don't care. */
                        }
                }
 
                if(!new_passwd)
+               {
                        new_passwd = prompt_for_new_password(stdin_passwd_get);
+               }
        }
        
+       if (enable_user)
+       {
+               acb_mask |= ACB_DISABLED;
+               acb_info &= ~ACB_DISABLED;
+       }
+
+       if (disable_user)
+       {
+               acb_mask |= ACB_DISABLED;
+               acb_info |= ACB_DISABLED;
+       }
+
+       if (set_no_password)
+       {
+               acb_mask |= ACB_PWNOTREQ;
+               acb_info |= ACB_PWNOTREQ;
+       }
+
+       if (wks_trust_account)
+       {
+               acb_mask |= ACB_WSTRUST;
+               acb_info |= ACB_WSTRUST;
+       }
+       else if (dom_trust_account)
+       {
+               acb_mask |= ACB_DOMTRUST;
+               acb_info |= ACB_DOMTRUST;
+       }
+       else
+       {
+               acb_mask |= ACB_NORMAL;
+               acb_info |= ACB_NORMAL;
+       }
+
        if (!password_change(remote_machine, user_name, old_passwd, new_passwd,
-                            add_user, enable_user, disable_user, set_no_password,
-                            trust_account)) {
+                            add_user, acb_info, acb_mask))
+       {
                fprintf(stderr,"Failed to change password entry for %s\n", user_name);
                return 1;
        } 
 
-       if(disable_user) {
+       if (disable_user)
+       {
                printf("User %s disabled.\n", user_name);
-       } else if(enable_user) {
+       }
+       if (enable_user)
+       {
                printf("User %s enabled.\n", user_name);
-       } else if (set_no_password) {
+       }
+       if (set_no_password)
+       {
                printf("User %s - set to no password.\n", user_name);
-       } else {
+       }
+       if (!disable_user && !enable_user && !set_no_password)
+       {
                printf("Password changed for user %s\n", user_name);
        }
        return 0;
@@ -457,8 +553,10 @@ static int process_nonroot(int argc, char *argv[])
        char *user_name = NULL;
        char *new_passwd = NULL;
 
-       while ((ch = getopt(argc, argv, "hD:r:sU:")) != EOF) {
-               switch(ch) {
+       while ((ch = getopt(argc, argv, "hD:r:sU:")) != EOF)
+       {
+               switch(ch)
+               {
                case 'D':
                        DEBUGLEVEL = atoi(optarg);
                        break;
@@ -523,8 +621,10 @@ static int process_nonroot(int argc, char *argv[])
                exit(0);
        }
 
-       if (!password_change(remote_machine, user_name, old_passwd, new_passwd,
-                            False, False, False, False, False)) {
+       if (!password_change(remote_machine, user_name,
+                            old_passwd, new_passwd,
+                            False, 0x0, 0x0))
+       {
                fprintf(stderr,"Failed to change password for %s\n", user_name);
                return 1;
        }
index 3383b29f3bc7994bab0da5daee4f595216c22141..ce7801ba5ca3bfba83ed6ee46a172ccbd535e537 100644 (file)
@@ -584,6 +584,8 @@ static BOOL change_password(const char *remote_machine, char *user_name,
                            BOOL add_user, BOOL enable_user, BOOL disable_user)
 {
        BOOL ret = False;
+       uint16 acb_info = 0;
+       uint16 acb_mask = 0;
        pstring err_str;
        pstring msg_str;
 
@@ -606,9 +608,22 @@ static BOOL change_password(const char *remote_machine, char *user_name,
                return False;
        }
        
-       ret = local_password_change(user_name, False, add_user, enable_user, 
-                                    disable_user, False, new_passwd, err_str, sizeof(err_str),
-                                        msg_str, sizeof(msg_str));
+       if (enable_user)
+       {
+               acb_mask |= ACB_DISABLED;
+               acb_info &= ~ACB_DISABLED;
+       }
+
+       if (disable_user)
+       {
+               acb_mask |= ACB_DISABLED;
+               acb_info |= ACB_DISABLED;
+       }
+
+       ret = local_password_change(user_name, add_user,
+                                   acb_info, acb_mask,
+                                   new_passwd, err_str, sizeof(err_str),
+                                   msg_str, sizeof(msg_str));
 
        if(*msg_str)
                printf("%s\n<p>", msg_str);