summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/smb.h1
-rw-r--r--source3/lib/util_pwdb.c2
-rw-r--r--source3/smbd/chgpasswd.c8
-rw-r--r--source3/utils/smbpasswd.c32
4 files changed, 40 insertions, 3 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 1c1a16b5b4..65746d219c 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -372,6 +372,7 @@ typedef struct nttime_info
#define ACB_SVRTRUST 0x0100 /* 1 = Server trust account */
#define ACB_PWNOEXP 0x0200 /* 1 = User password does not expire */
#define ACB_AUTOLOCK 0x0400 /* 1 = Account auto locked */
+#define ACB_PWLOCK 0x0800 /* 1 = Password is locked and connot be changed remotely */
#define MAX_HOURS_LEN 32
diff --git a/source3/lib/util_pwdb.c b/source3/lib/util_pwdb.c
index 495193e571..a678e4b063 100644
--- a/source3/lib/util_pwdb.c
+++ b/source3/lib/util_pwdb.c
@@ -225,6 +225,7 @@ char *pwdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
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';
+ if (acct_ctrl & ACB_PWLOCK ) acct_str[i++] = 'P';
for ( ; i < length - 2 ; i++ )
{
@@ -273,6 +274,7 @@ uint16 pwdb_decode_acct_ctrl(const 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 'P': { acct_ctrl |= ACB_PWLOCK ; break; /* 'P'assword cannot be changed remotely */ }
case ' ': { break; }
case ':':
case '\n':
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 167fce6e8c..852d6aa618 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -571,6 +571,14 @@ BOOL pass_oem_change(char *user,
&sampw,
new_passwd, sizeof(new_passwd));
+ /* now we check to see if we are actually allowed to change the
+ password. */
+
+ if (ret && (sampw->acct_ctrl & ACB_PWLOCK))
+ {
+ ret = False;
+ }
+
/*
* At this point we have the new case-sensitive plaintext
* password in the fstring new_passwd. If we wanted to synchronise
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index 83b9b0bdc9..e1c6666820 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -70,7 +70,10 @@ static void usage(void)
printf(" -n set no password\n");
printf(" -m workstation trust account\n");
printf(" -i inter-domain trust account\n");
+ printf(" -p user cannot change password\n");
+ printf(" -x user can change password\n");
}
+
exit(1);
}
@@ -286,13 +289,15 @@ static int process_root(int argc, char *argv[])
BOOL enable_user = False;
BOOL set_no_password = False;
BOOL stdin_passwd_get = False;
+ BOOL lock_password = False;
+ BOOL unlock_password = False;
char *user_name = NULL;
char *new_domain = NULL;
char *new_passwd = NULL;
char *old_passwd = NULL;
char *remote_machine = NULL;
- while ((ch = getopt(argc, argv, "adehimnj:r:sR:D:U:")) != EOF)
+ while ((ch = getopt(argc, argv, "adehimnpxj:r:sR:D:U:")) != EOF)
{
switch(ch)
{
@@ -362,6 +367,16 @@ static int process_root(int argc, char *argv[])
user_name = optarg;
break;
}
+ case 'p':
+ {
+ lock_password = True;
+ break;
+ }
+ case 'x':
+ {
+ unlock_password = True;
+ break;
+ }
default:
{
usage();
@@ -497,6 +512,18 @@ static int process_root(int argc, char *argv[])
acb_info |= ACB_PWNOTREQ;
}
+ if (lock_password)
+ {
+ acb_mask |= ACB_PWLOCK;
+ acb_info |= ACB_PWLOCK;
+ }
+
+ if (unlock_password)
+ {
+ acb_mask |= ACB_PWLOCK;
+ acb_info &= ~ACB_PWLOCK;
+ }
+
if (wks_trust_account)
{
acb_mask |= ACB_WSTRUST;
@@ -552,7 +579,7 @@ static int process_nonroot(int argc, char *argv[])
char *remote_machine = NULL;
char *user_name = NULL;
char *new_passwd = NULL;
-
+
while ((ch = getopt(argc, argv, "hD:r:sU:")) != EOF)
{
switch(ch)
@@ -607,7 +634,6 @@ static int process_nonroot(int argc, char *argv[])
remote_machine = "127.0.0.1";
}
-
if (remote_machine != NULL) {
old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
}