summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-09-24 22:33:13 +0000
committerJeremy Allison <jra@samba.org>1998-09-24 22:33:13 +0000
commite96747a8e3b9ea5a79c4258e55d7e8f3bf0bf193 (patch)
treedeeeb4ce724bfdf1dd56cb96ea4f6c5b2317bd1c
parent203a97e39e7ae7e5511f74dffea0778e7fa6db07 (diff)
downloadsamba-e96747a8e3b9ea5a79c4258e55d7e8f3bf0bf193.tar.gz
samba-e96747a8e3b9ea5a79c4258e55d7e8f3bf0bf193.tar.xz
samba-e96747a8e3b9ea5a79c4258e55d7e8f3bf0bf193.zip
Integration of Anders Blomdell <anders.blomdell@control.lth.se>'s
smbpasswd changes. Not exactly the same as his code - several changes. Jeremy.
-rw-r--r--source/include/proto.h2
-rw-r--r--source/include/smb.h6
-rw-r--r--source/passdb/ldap.c2
-rw-r--r--source/passdb/nispass.c2
-rw-r--r--source/passdb/passdb.c52
-rw-r--r--source/passdb/smbpass.c124
-rw-r--r--source/script/addtosmbpass6
-rwxr-xr-xsource/script/mksmbpasswd.sh2
-rw-r--r--source/smbd/oplock.c39
-rw-r--r--source/utils/smbpasswd.c138
10 files changed, 245 insertions, 128 deletions
diff --git a/source/include/proto.h b/source/include/proto.h
index cbd4f07b2f3..fd77c45ee35 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -1101,7 +1101,7 @@ void pdb_init_smb(struct smb_passwd *user);
void pdb_init_sam(struct sam_passwd *user);
struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user);
struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user);
-char *pdb_encode_acct_ctrl(uint16 acct_ctrl);
+char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
uint16 pdb_decode_acct_ctrl(char *p);
BOOL pdb_gethexpwd(char *p, char *pwd);
BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid);
diff --git a/source/include/smb.h b/source/include/smb.h
index 842aeb57be0..bec14ddd137 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -1601,6 +1601,12 @@ extern int unix_ERR_code;
__FILE__, __LINE__)), smb_panic("assert failed")))
#define SMB_ASSERT_ARRAY(a,n) SMB_ASSERT((sizeof(a)/sizeof((a)[0])) >= (n))
+/*
+ * Size of new password account encoding string. DO NOT CHANGE.
+ */
+
+#define NEW_PW_FORMAT_SPACE_PADDED_LEN 14
+
#endif /* _SMB_H */
#include "ntdomain.h"
diff --git a/source/passdb/ldap.c b/source/passdb/ldap.c
index e27b4fbea7b..80ba6be3a79 100644
--- a/source/passdb/ldap.c
+++ b/source/passdb/ldap.c
@@ -576,7 +576,7 @@ static BOOL modadd_ldappwd_entry(struct smb_passwd *newpwd, int flag)
make_a_mod(&mods, ldap_state, "rid", rid);
make_a_mod(&mods, ldap_state, "pwdLastSet", lst);
- make_a_mod(&mods, ldap_state, "userAccountControl", pdb_encode_acct_ctrl(newpwd->acct_ctrl));
+ make_a_mod(&mods, ldap_state, "userAccountControl", pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
switch(flag)
{
diff --git a/source/passdb/nispass.c b/source/passdb/nispass.c
index 04c1c23b2e6..4a2a7723d64 100644
--- a/source/passdb/nispass.c
+++ b/source/passdb/nispass.c
@@ -376,7 +376,7 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
slprintf(smb_grpid, sizeof(smb_grpid), "%u", newpwd->smb_grpid);
slprintf(group_rid, sizeof(group_rid), "0x%x", newpwd->group_rid);
- safe_strcpy(acb, pdb_encode_acct_ctrl(newpwd->acct_ctrl), sizeof(acb));
+ safe_strcpy(acb, pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), sizeof(acb));
set_single_attribute(&new_obj, NPF_NAME , newpwd->smb_name , strlen(newpwd->smb_name) , 0);
set_single_attribute(&new_obj, NPF_UID , uid , strlen(uid) , 0);
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index 02f30b24c87..6633088245a 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -491,26 +491,35 @@ struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user)
/**********************************************************
Encode the account control bits into a string.
+ length = length of string to encode into (including terminating
+ null). length *MUST BE MORE THAN 2* !
**********************************************************/
-char *pdb_encode_acct_ctrl(uint16 acct_ctrl)
+
+char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
{
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';
+ size_t i = 0;
+
+ acct_str[i++] = '[';
+
+ if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
+ if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
+ if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
+ if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
+ if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
+ if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
+ if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
+ if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
+ if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
+ if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
+ if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
+
+ for ( ; i < length - 2 ; i++ ) { acct_str[i] = ' '; }
+
+ i = length - 2;
+ acct_str[i++] = ']';
+ acct_str[i++] = '\0';
+
return acct_str;
}
@@ -538,15 +547,8 @@ uint16 pdb_decode_acct_ctrl(char *p)
{
switch (*p)
{
-#if 0
- /*
- * Hmmm. Don't allow these to be set/read independently
- * of the actual password fields. We don't want a mismatch.
- * JRA.
- */
case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
-#endif
case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
@@ -556,7 +558,7 @@ uint16 pdb_decode_acct_ctrl(char *p)
case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
-
+ case ' ':
case ':':
case '\n':
case '\0':
diff --git a/source/passdb/smbpass.c b/source/passdb/smbpass.c
index a2b648b2fd2..cff049dcd5f 100644
--- a/source/passdb/smbpass.c
+++ b/source/passdb/smbpass.c
@@ -264,7 +264,7 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
p++;
if(*p == ':') {
p++;
- if(*p && StrnCaseCmp((char *)p, "LCT-", 4)) {
+ if(*p && (StrnCaseCmp((char *)p, "LCT-", 4)==0)) {
int i;
p += 4;
for(i = 0; i < 8; i++) {
@@ -473,7 +473,7 @@ Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
return False;
}
- new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + 5 + 1 + 13 + 2;
+ new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2;
if((new_entry = (char *)malloc( new_entry_length )) == NULL) {
DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \
@@ -518,8 +518,7 @@ Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
/* Add the account encoding and the last change time. */
slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n",
- pdb_encode_acct_ctrl(newpwd->acct_ctrl),
- (uint32)time(NULL));
+ pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32)time(NULL));
#ifdef DEBUG_PASSWORD
DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d entry_len %d made line |%s|",
@@ -538,9 +537,11 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
}
endsmbfilepwent(fp);
+ free(new_entry);
return False;
}
+ free(new_entry);
endsmbfilepwent(fp);
return True;
}
@@ -654,7 +655,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
*
* or,
*
- * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
+ * username:uid:[32hex bytes]:[32hex bytes]:[attributes]:LCT-XXXXXXXX:...ignored.
*
* if Windows NT compatible passwords are also present.
*/
@@ -772,11 +773,31 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
if (*p == '[') {
i = 0;
- p++;
+ encode_bits[i++] = *p++;
while((linebuf_len > PTR_DIFF(p, linebuf)) && (*p != ']'))
encode_bits[i++] = *p++;
- encode_bits[i] = '\0';
+ encode_bits[i++] = ']';
+ encode_bits[i++] = '\0';
+
+ if(i == NEW_PW_FORMAT_SPACE_PADDED_LEN) {
+ /*
+ * We are using a new format, space padded
+ * acct ctrl field. Encode the given acct ctrl
+ * bits into it.
+ */
+ fstrcpy(encode_bits, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
+ } else {
+ /*
+ * If using the old format and the ACB_DISABLED or
+ * ACB_PWNOTREQ are set then set the lanman and NT passwords to NULL
+ * here as we have no space to encode the change.
+ */
+ if(pwd->acct_ctrl & (ACB_DISABLED|ACB_PWNOTREQ)) {
+ pwd->smb_passwd = NULL;
+ pwd->smb_nt_passwd = NULL;
+ }
+ }
/* Go past the ']' */
if(linebuf_len > PTR_DIFF(p, linebuf))
@@ -785,8 +806,8 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
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((char *)p, "LCT-", 4)) {
+ /* We should be pointing at the LCT entry. */
+ if((linebuf_len > (PTR_DIFF(p, linebuf) + 13)) && (StrnCaseCmp((char *)p, "LCT-", 4) == 0)) {
p += 4;
for(i = 0; i < 8; i++) {
@@ -807,39 +828,6 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
/* Entry is correctly formed. */
- /*
- * Do an atomic write into the file at the position defined by
- * seekpos.
- */
-
- /* The mod user write needs to be atomic - so get the fd from
- the fp and do a raw write() call.
- */
-
- fd = fileno(fp);
-
- if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
- DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
- fclose(fp);
- return False;
- }
-
- /* Sanity check - ensure the character is a ':' */
- if (read(fd, &c, 1) != 1) {
- DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
- fclose(fp);
- return False;
- }
-
- if (c != ':') {
- DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
- fclose(fp);
- return False;
- }
-
/* Create the 32 byte representation of the new p16 */
if(pwd->smb_passwd != NULL) {
for (i = 0; i < 16; i++) {
@@ -854,7 +842,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
/* Add on the NT md4 hash */
ascii_p16[32] = ':';
- wr_len = 65;
+ wr_len = 66;
if (pwd->smb_nt_passwd != NULL) {
for (i = 0; i < 16; i++) {
slprintf(&ascii_p16[(i*2)+33], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_nt_passwd[i]);
@@ -865,6 +853,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
else
fstrcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
}
+ ascii_p16[65] = ':';
/* Add on the account info bits and the time of last
password change. */
@@ -874,7 +863,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
if(got_pass_last_set_time) {
slprintf(&ascii_p16[strlen(ascii_p16)],
sizeof(ascii_p16)-(strlen(ascii_p16)+1),
- ":[%s]:TLC-%08X:",
+ "%s:LCT-%08X:",
encode_bits, (uint32)pwd->pass_last_set_time );
wr_len = strlen(ascii_p16);
}
@@ -884,6 +873,53 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
dump_data(100, ascii_p16, wr_len);
#endif
+ if(wr_len > sizeof(linebuf)) {
+ DEBUG(0, ("mod_smbfilepwd_entry: line to write (%d) is too long.\n", wr_len+1));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
+ fclose(fp);
+ return (False);
+ }
+
+ /*
+ * Do an atomic write into the file at the position defined by
+ * seekpos.
+ */
+
+ /* The mod user write needs to be atomic - so get the fd from
+ the fp and do a raw write() call.
+ */
+
+ fd = fileno(fp);
+
+ if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
+ DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
+ fclose(fp);
+ return False;
+ }
+
+ /* Sanity check - ensure the areas we are writing are framed by ':' */
+ if (read(fd, linebuf, wr_len+1) != wr_len+1) {
+ DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
+ fclose(fp);
+ return False;
+ }
+
+ if ((linebuf[0] != ':') || (linebuf[wr_len] != ':')) {
+ DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
+ fclose(fp);
+ return False;
+ }
+
+ if (sys_lseek(fd, pwd_seekpos, SEEK_SET) != pwd_seekpos) {
+ DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
+ pw_file_unlock(lockfd,&pw_file_lock_depth);
+ fclose(fp);
+ return False;
+ }
+
if (write(fd, ascii_p16, wr_len) != wr_len) {
DEBUG(0, ("mod_smbfilepwd_entry: write failed in passwd file %s\n", pfile));
pw_file_unlock(lockfd,&pw_file_lock_depth);
diff --git a/source/script/addtosmbpass b/source/script/addtosmbpass
index 42af518397c..5a41022a270 100644
--- a/source/script/addtosmbpass
+++ b/source/script/addtosmbpass
@@ -48,11 +48,11 @@ BEGIN {
}
END {
fmt = "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:";
- fmt = fmt "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n";
+ fmt = fmt "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U]:LCT-00000000:%s:\n";
for(name in names) {
while ((getline < pwdf) > 0) {
if ($1 == name) {
- printf(fmt, $1, $3, $5, $6, $7);
+ printf(fmt, $1, $3, $5);
close(pwdf);
notfound = "";
break;
@@ -65,7 +65,7 @@ END {
command = ypmatch " " name " passwd";
command | getline;
if (NF > 0) {
- printf(fmt, $1, $3, $5, $6, $7);
+ printf(fmt, $1, $3, $5);
}
close(command);
}
diff --git a/source/script/mksmbpasswd.sh b/source/script/mksmbpasswd.sh
index 6e592acd652..10acc1257d7 100755
--- a/source/script/mksmbpasswd.sh
+++ b/source/script/mksmbpasswd.sh
@@ -2,5 +2,5 @@
awk 'BEGIN {FS=":"
printf("#\n# SMB password file.\n#\n")
}
-{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }
+{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U]:LCT-00000000:%s\n", $1, $3, $5) }
'
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index d73fcda117d..b418e7cd549 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -240,16 +240,47 @@ BOOL set_file_oplock(files_struct *fsp)
{
#if defined(HAVE_KERNEL_OPLOCKS)
if(lp_kernel_oplocks()) {
- if(fcntl(fsp->fd_ptr->fd, F_OPLKREG, oplock_pipe_write) < 0) {
- if(errno != EAGAIN) {
+#if 0 /* for now. */
+ extern struct current_user current_user;
+#endif
+ int saved_errno;
+ int fcntl_ret;
+
+#if 0 /* for now. */
+ /*
+ * Go back to being root.
+ */
+
+ unbecome_user();
+#endif
+
+ fcntl_ret = fcntl(fsp->fd_ptr->fd, F_OPLKREG, oplock_pipe_write);
+ saved_errno = errno;
+
+#if 0 /* for now. */
+ /*
+ * Go back to being the correct user.
+ */
+ if(!become_user(fsp->conn, current_user.vuid))
+ {
+ DEBUG( 0, ( "set_file_oplock: unable to re-become user!" ) );
+ DEBUGADD( 0, ( "Shutting down server\n" ) );
+ close_sockets();
+ close(oplock_sock);
+ exit_server("unable to re-become user");
+ }
+#endif
+
+ if(fcntl_ret < 0) {
+ if(saved_errno != EAGAIN) {
DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \
inode = %.0f. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode,
strerror(errno) ));
} else {
- DEBUG(5,("set_file_oplock: Refused oplock on file %s, dev = %x, \
+ DEBUG(5,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
inode = %.0f. Another process had the file open.\n",
- fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode ));
+ fsp->fsp_name, fsp->fd_ptr->fd, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode ));
}
return False;
}
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index 03553b0ea96..b97b0c765fd 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -32,7 +32,7 @@ static char *prog_name;
static void usage(char *name, BOOL is_root)
{
if(is_root)
- fprintf(stderr, "Usage is : %s [-D DEBUGLEVEL] [-a] [-d] [-m] [-n] [username] [password]\n\
+ fprintf(stderr, "Usage is : %s [-D DEBUGLEVEL] [-a] [-d] [-e] [-m] [-n] [username] [password]\n\
%s: [-R <name resolve order>] [-D DEBUGLEVEL] [-j DOMAINNAME] [-r machine] [-U remote_username] [username] [password]\n%s: [-h]\n", name, name, name);
else
fprintf(stderr, "Usage is : %s [-h] [-D DEBUGLEVEL] [-r machine] [-U remote_username] [password]\n", name);
@@ -112,6 +112,56 @@ unable to join domain.\n", prog_name);
return (int)ret;
}
+/*************************************************************
+ Utility function to create password hashes.
+*************************************************************/
+
+static void create_new_hashes( char *new_passwd, uchar *new_p16, uchar *new_nt_p16)
+{
+ memset(new_nt_p16, '\0', 16);
+ E_md4hash((uchar *) new_passwd, new_nt_p16);
+
+ /* Mangle the password into Lanman format */
+ new_passwd[14] = '\0';
+ strupper(new_passwd);
+
+ /*
+ * Calculate the SMB (lanman) hash functions of the new password.
+ */
+
+ memset(new_p16, '\0', 16);
+ E_P16((uchar *) new_passwd, new_p16);
+}
+
+/*************************************************************
+ Utility function to prompt for new password.
+*************************************************************/
+
+static void prompt_for_new_password(char *new_passwd)
+{
+ char *p;
+
+ new_passwd[0] = '\0';
+
+ p = getpass("New SMB password:");
+
+ strncpy(new_passwd, p, sizeof(fstring));
+ new_passwd[sizeof(fstring)-1] = '\0';
+
+ p = getpass("Retype new SMB password:");
+
+ if (strncmp(p, new_passwd, sizeof(fstring)-1))
+ {
+ fprintf(stderr, "%s: Mismatch - password unchanged.\n", prog_name);
+ exit(1);
+ }
+
+ if (new_passwd[0] == '\0') {
+ printf("Password not set\n");
+ exit(0);
+ }
+}
+
/*********************************************************
Start here.
**********************************************************/
@@ -140,6 +190,7 @@ int main(int argc, char **argv)
BOOL got_new_pass = False;
BOOL trust_account = False;
BOOL disable_user = False;
+ BOOL enable_user = False;
BOOL set_no_password = False;
BOOL joining_domain = False;
char *new_domain = NULL;
@@ -202,7 +253,7 @@ int main(int argc, char **argv)
is_root = (real_uid == 0);
- while ((ch = getopt(argc, argv, "adhmnj:r:R:D:U:")) != EOF) {
+ while ((ch = getopt(argc, argv, "adehmnj:r:R:D:U:")) != EOF) {
switch(ch) {
case 'a':
if(is_root)
@@ -218,6 +269,14 @@ int main(int argc, char **argv)
} else
usage(prog_name, is_root);
break;
+ case 'e':
+ if(is_root) {
+ enable_user = True;
+ got_new_pass = True;
+ fstrcpy(new_passwd, "XXXXXX");
+ } else
+ usage(prog_name, is_root);
+ break;
case 'D':
DEBUGLEVEL = atoi(optarg);
break;
@@ -337,7 +396,17 @@ int main(int argc, char **argv)
} else {
if(add_user) {
- fprintf(stderr, "%s: Only root can set anothers password.\n", prog_name);
+ fprintf(stderr, "%s: Only root can add a user.\n", prog_name);
+ usage(prog_name, False);
+ }
+
+ if(disable_user) {
+ fprintf(stderr, "%s: Only root can disable a user.\n", prog_name);
+ usage(prog_name, False);
+ }
+
+ if(enable_user) {
+ fprintf(stderr, "%s: Only root can enable a user.\n", prog_name);
usage(prog_name, False);
}
@@ -392,22 +461,8 @@ int main(int argc, char **argv)
fstrcpy(old_passwd, p);
}
- if (!got_new_pass) {
- new_passwd[0] = '\0';
-
- p = getpass("New SMB password:");
-
- strncpy(new_passwd, p, sizeof(fstring));
- new_passwd[sizeof(fstring)-1] = '\0';
-
- p = getpass("Retype new SMB password:");
-
- if (strncmp(p, new_passwd, sizeof(fstring)-1))
- {
- fprintf(stderr, "%s: Mismatch - password unchanged.\n", prog_name);
- exit(1);
- }
- }
+ if (!got_new_pass)
+ prompt_for_new_password(new_passwd);
if (new_passwd[0] == '\0') {
printf("Password not set\n");
@@ -493,25 +548,14 @@ int main(int argc, char **argv)
/* Calculate the MD4 hash (NT compatible) of the new password. */
- memset(new_nt_p16, '\0', 16);
- E_md4hash((uchar *) new_passwd, new_nt_p16);
-
- /* Mangle the password into Lanman format */
- new_passwd[14] = '\0';
- strupper(new_passwd);
-
- /*
- * Calculate the SMB (lanman) hash functions of the new password.
- */
-
- memset(new_p16, '\0', 16);
- E_P16((uchar *) new_passwd, new_p16);
-
+ create_new_hashes( new_passwd, new_p16, new_nt_p16);
+
/*
* Open the smbpaswd file.
*/
vp = startsmbpwent(True);
if (!vp && errno == ENOENT) {
+ fprintf(stderr,"%s: smbpasswd file did not exist - attempting to create it.\n", prog_name);
fp = fopen(lp_smb_passwd_file(), "w");
if (fp) {
fprintf(fp, "# Samba SMB password file\n");
@@ -578,23 +622,19 @@ int main(int argc, char **argv)
* and the valid last change time.
*/
- if(disable_user) {
- /*
- * This currently won't work as it means changing
- * the length of the record. JRA.
- */
+ if(disable_user)
smb_pwent->acct_ctrl |= ACB_DISABLED;
- smb_pwent->smb_passwd = NULL;
- smb_pwent->smb_nt_passwd = NULL;
- } else if (set_no_password) {
- /*
- * This currently won't work as it means changing
- * the length of the record. JRA.
- */
+ else if (enable_user) {
+ if(smb_pwent->smb_passwd == NULL) {
+ prompt_for_new_password(new_passwd);
+ create_new_hashes( new_passwd, new_p16, new_nt_p16);
+ 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;
- smb_pwent->smb_passwd = NULL;
- smb_pwent->smb_nt_passwd = NULL;
- } else {
+ else {
smb_pwent->smb_passwd = new_p16;
smb_pwent->smb_nt_passwd = new_nt_p16;
}
@@ -609,6 +649,8 @@ int main(int argc, char **argv)
endsmbpwent(vp);
if(disable_user)
printf("User %s disabled.\n", user_name);
+ else if(enable_user)
+ printf("User %s enabled.\n", user_name);
else if (set_no_password)
printf("User %s - set to no password.\n", user_name);
else