diff options
-rw-r--r-- | source3/include/smb.h | 1 | ||||
-rw-r--r-- | source3/lib/util_pwdb.c | 2 | ||||
-rw-r--r-- | source3/smbd/chgpasswd.c | 8 | ||||
-rw-r--r-- | source3/utils/smbpasswd.c | 32 |
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); } |