2 Unix SMB/Netbios implementation.
4 change a password in a local smbpasswd file
5 Copyright (C) Andrew Tridgell 1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /*************************************************************
26 add a new user to the local smbpasswd file
27 *************************************************************/
28 static BOOL
add_new_user(char *user_name
, uid_t uid
, BOOL trust_account
,
29 BOOL disable_user
, BOOL set_no_password
,
30 uchar
*new_p16
, uchar
*new_nt_p16
)
32 struct smb_passwd new_smb_pwent
;
34 /* Create a new smb passwd entry and set it to the given password. */
35 new_smb_pwent
.smb_userid
= uid
;
36 new_smb_pwent
.smb_name
= user_name
;
37 new_smb_pwent
.smb_passwd
= NULL
;
38 new_smb_pwent
.smb_nt_passwd
= NULL
;
39 new_smb_pwent
.acct_ctrl
= (trust_account
? ACB_WSTRUST
: ACB_NORMAL
);
42 new_smb_pwent
.acct_ctrl
|= ACB_DISABLED
;
43 } else if (set_no_password
) {
44 new_smb_pwent
.acct_ctrl
|= ACB_PWNOTREQ
;
46 new_smb_pwent
.smb_passwd
= new_p16
;
47 new_smb_pwent
.smb_nt_passwd
= new_nt_p16
;
50 return add_smbpwd_entry(&new_smb_pwent
);
54 /*************************************************************
55 change a password entry in the local smbpasswd file
56 *************************************************************/
58 BOOL
local_password_change(char *user_name
, BOOL trust_account
, BOOL add_user
,
59 BOOL enable_user
, BOOL disable_user
, BOOL set_no_password
,
61 char *err_str
, size_t err_str_len
,
62 char *msg_str
, size_t msg_str_len
)
66 struct smb_passwd
*smb_pwent
;
73 pwd
= sys_getpwnam(user_name
);
76 * Check for a local account.
80 slprintf(err_str
, err_str_len
- 1, "User %s does not \
81 exist in system password file (usually /etc/passwd). Cannot add \
82 account without a valid local system user.\n", user_name
);
86 /* Calculate the MD4 hash (NT compatible) of the new password. */
87 nt_lm_owf_gen(new_passwd
, new_nt_p16
, new_p16
);
90 * Open the smbpaswd file.
92 vp
= startsmbpwent(True
);
93 if (!vp
&& errno
== ENOENT
) {
95 slprintf(msg_str
,msg_str_len
-1,
96 "smbpasswd file did not exist - attempting to create it.\n");
97 fp
= sys_fopen(lp_smb_passwd_file(), "w");
99 fprintf(fp
, "# Samba SMB password file\n");
101 vp
= startsmbpwent(True
);
106 slprintf(err_str
, err_str_len
-1, "Cannot open file %s. Error was %s\n",
107 lp_smb_passwd_file(), strerror(errno
) );
111 /* Get the smb passwd entry for this user */
112 smb_pwent
= getsmbpwnam(user_name
);
113 if (smb_pwent
== NULL
) {
114 if(add_user
== False
) {
115 slprintf(err_str
, err_str_len
-1,
116 "Failed to find entry for user %s.\n", pwd
->pw_name
);
121 if (add_new_user(user_name
, pwd
->pw_uid
, trust_account
, disable_user
,
122 set_no_password
, new_p16
, new_nt_p16
)) {
123 slprintf(msg_str
, msg_str_len
-1, "Added user %s.\n", user_name
);
127 slprintf(err_str
, err_str_len
-1, "Failed to add entry for user %s.\n", user_name
);
132 /* the entry already existed */
137 * We are root - just write the new password
138 * and the valid last change time.
142 smb_pwent
->acct_ctrl
|= ACB_DISABLED
;
143 } else if (enable_user
) {
144 if(smb_pwent
->smb_passwd
== NULL
) {
145 smb_pwent
->smb_passwd
= new_p16
;
146 smb_pwent
->smb_nt_passwd
= new_nt_p16
;
148 smb_pwent
->acct_ctrl
&= ~ACB_DISABLED
;
149 } else if (set_no_password
) {
150 smb_pwent
->acct_ctrl
|= ACB_PWNOTREQ
;
151 /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
152 smb_pwent
->smb_passwd
= NULL
;
153 smb_pwent
->smb_nt_passwd
= NULL
;
156 * If we're dealing with setting a completely empty user account
157 * ie. One with a password of 'XXXX', but not set disabled (like
158 * an account created from scratch) then if the old password was
159 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
160 * We remove that as we're giving this user their first password
161 * and the decision hasn't really been made to disable them (ie.
162 * don't create them disabled). JRA.
164 if((smb_pwent
->smb_passwd
== NULL
) && (smb_pwent
->acct_ctrl
& ACB_DISABLED
))
165 smb_pwent
->acct_ctrl
&= ~ACB_DISABLED
;
166 smb_pwent
->acct_ctrl
&= ~ACB_PWNOTREQ
;
167 smb_pwent
->smb_passwd
= new_p16
;
168 smb_pwent
->smb_nt_passwd
= new_nt_p16
;
171 if(mod_smbpwd_entry(smb_pwent
,True
) == False
) {
172 slprintf(err_str
, err_str_len
-1, "Failed to modify entry for user %s.\n",