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 *************************************************************/
29 static BOOL
add_new_user(char *user_name
, uid_t uid
, int local_flags
,
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
.pass_last_set_time
= time(NULL
);
40 new_smb_pwent
.acct_ctrl
= ((local_flags
& LOCAL_TRUST_ACCOUNT
) ? ACB_WSTRUST
: ACB_NORMAL
);
42 if(local_flags
& LOCAL_DISABLE_USER
) {
43 new_smb_pwent
.acct_ctrl
|= ACB_DISABLED
;
46 if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
47 new_smb_pwent
.acct_ctrl
|= ACB_PWNOTREQ
;
49 new_smb_pwent
.smb_passwd
= new_p16
;
50 new_smb_pwent
.smb_nt_passwd
= new_nt_p16
;
54 return add_smbpwd_entry(&new_smb_pwent
);
58 /*************************************************************
59 change a password entry in the local smbpasswd file
60 *************************************************************/
62 BOOL
local_password_change(char *user_name
, int local_flags
,
64 char *err_str
, size_t err_str_len
,
65 char *msg_str
, size_t msg_str_len
)
67 struct passwd
*pwd
= NULL
;
69 struct smb_passwd
*smb_pwent
;
76 if (local_flags
& LOCAL_ADD_USER
) {
79 * Check for a local account - if we're adding only.
82 if(!(pwd
= sys_getpwnam(user_name
))) {
83 slprintf(err_str
, err_str_len
- 1, "User %s does not \
84 exist in system password file (usually /etc/passwd). Cannot add \
85 account without a valid local system user.\n", user_name
);
90 /* Calculate the MD4 hash (NT compatible) of the new password. */
91 nt_lm_owf_gen(new_passwd
, new_nt_p16
, new_p16
);
94 * Open the smbpaswd file.
96 vp
= startsmbpwent(True
);
97 if (!vp
&& errno
== ENOENT
) {
99 slprintf(msg_str
,msg_str_len
-1,
100 "smbpasswd file did not exist - attempting to create it.\n");
101 fp
= sys_fopen(lp_smb_passwd_file(), "w");
103 fprintf(fp
, "# Samba SMB password file\n");
105 vp
= startsmbpwent(True
);
110 slprintf(err_str
, err_str_len
-1, "Cannot open file %s. Error was %s\n",
111 lp_smb_passwd_file(), strerror(errno
) );
115 /* Get the smb passwd entry for this user */
116 smb_pwent
= getsmbpwnam(user_name
);
117 if (smb_pwent
== NULL
) {
118 if(!(local_flags
& LOCAL_ADD_USER
)) {
119 slprintf(err_str
, err_str_len
-1,
120 "Failed to find entry for user %s.\n", user_name
);
125 if (add_new_user(user_name
, pwd
->pw_uid
, local_flags
, new_p16
, new_nt_p16
)) {
126 slprintf(msg_str
, msg_str_len
-1, "Added user %s.\n", user_name
);
130 slprintf(err_str
, err_str_len
-1, "Failed to add entry for user %s.\n", user_name
);
135 /* the entry already existed */
136 local_flags
&= ~LOCAL_ADD_USER
;
140 * We are root - just write the new password
141 * and the valid last change time.
144 if(local_flags
& LOCAL_DISABLE_USER
) {
145 smb_pwent
->acct_ctrl
|= ACB_DISABLED
;
146 } else if (local_flags
& LOCAL_ENABLE_USER
) {
147 if(smb_pwent
->smb_passwd
== NULL
) {
148 smb_pwent
->smb_passwd
= new_p16
;
149 smb_pwent
->smb_nt_passwd
= new_nt_p16
;
151 smb_pwent
->acct_ctrl
&= ~ACB_DISABLED
;
152 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
153 smb_pwent
->acct_ctrl
|= ACB_PWNOTREQ
;
154 /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
155 smb_pwent
->smb_passwd
= NULL
;
156 smb_pwent
->smb_nt_passwd
= NULL
;
159 * If we're dealing with setting a completely empty user account
160 * ie. One with a password of 'XXXX', but not set disabled (like
161 * an account created from scratch) then if the old password was
162 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
163 * We remove that as we're giving this user their first password
164 * and the decision hasn't really been made to disable them (ie.
165 * don't create them disabled). JRA.
167 if((smb_pwent
->smb_passwd
== NULL
) && (smb_pwent
->acct_ctrl
& ACB_DISABLED
))
168 smb_pwent
->acct_ctrl
&= ~ACB_DISABLED
;
169 smb_pwent
->acct_ctrl
&= ~ACB_PWNOTREQ
;
170 smb_pwent
->smb_passwd
= new_p16
;
171 smb_pwent
->smb_nt_passwd
= new_nt_p16
;
174 if(local_flags
& LOCAL_DELETE_USER
) {
175 if (del_smbpwd_entry(user_name
)==False
) {
176 slprintf(err_str
,err_str_len
-1, "Failed to delete entry for user %s.\n", user_name
);
180 slprintf(msg_str
, msg_str_len
-1, "Deleted user %s.\n", user_name
);
182 if(mod_smbpwd_entry(smb_pwent
,True
) == False
) {
183 slprintf(err_str
, err_str_len
-1, "Failed to modify entry for user %s.\n", user_name
);
187 if(local_flags
& LOCAL_DISABLE_USER
)
188 slprintf(msg_str
, msg_str_len
-1, "Disabled user %s.\n", user_name
);
189 else if (local_flags
& LOCAL_ENABLE_USER
)
190 slprintf(msg_str
, msg_str_len
-1, "Enabled user %s.\n", user_name
);
191 else if (local_flags
& LOCAL_SET_NO_PASSWORD
)
192 slprintf(msg_str
, msg_str_len
-1, "User %s password set to none.\n", user_name
);