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
;
44 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
45 new_smb_pwent
.acct_ctrl
|= ACB_PWNOTREQ
;
47 new_smb_pwent
.smb_passwd
= new_p16
;
48 new_smb_pwent
.smb_nt_passwd
= new_nt_p16
;
52 return add_smbpwd_entry(&new_smb_pwent
);
56 /*************************************************************
57 change a password entry in the local smbpasswd file
58 *************************************************************/
60 BOOL
local_password_change(char *user_name
, int local_flags
,
62 char *err_str
, size_t err_str_len
,
63 char *msg_str
, size_t msg_str_len
)
65 struct passwd
*pwd
= NULL
;
67 struct smb_passwd
*smb_pwent
;
74 if (local_flags
& LOCAL_ADD_USER
) {
77 * Check for a local account - if we're adding only.
80 if(!(pwd
= sys_getpwnam(user_name
))) {
81 slprintf(err_str
, err_str_len
- 1, "User %s does not \
82 exist in system password file (usually /etc/passwd). Cannot add \
83 account without a valid local system user.\n", user_name
);
88 /* Calculate the MD4 hash (NT compatible) of the new password. */
89 nt_lm_owf_gen(new_passwd
, new_nt_p16
, new_p16
);
92 * Open the smbpaswd file.
94 vp
= startsmbpwent(True
);
95 if (!vp
&& errno
== ENOENT
) {
97 slprintf(msg_str
,msg_str_len
-1,
98 "smbpasswd file did not exist - attempting to create it.\n");
99 fp
= sys_fopen(lp_smb_passwd_file(), "w");
101 fprintf(fp
, "# Samba SMB password file\n");
103 vp
= startsmbpwent(True
);
108 slprintf(err_str
, err_str_len
-1, "Cannot open file %s. Error was %s\n",
109 lp_smb_passwd_file(), strerror(errno
) );
113 /* Get the smb passwd entry for this user */
114 smb_pwent
= getsmbpwnam(user_name
);
115 if (smb_pwent
== NULL
) {
116 if(!(local_flags
& LOCAL_ADD_USER
)) {
117 slprintf(err_str
, err_str_len
-1,
118 "Failed to find entry for user %s.\n", user_name
);
123 if (add_new_user(user_name
, pwd
->pw_uid
, local_flags
, new_p16
, new_nt_p16
)) {
124 slprintf(msg_str
, msg_str_len
-1, "Added user %s.\n", user_name
);
128 slprintf(err_str
, err_str_len
-1, "Failed to add entry for user %s.\n", user_name
);
133 /* the entry already existed */
134 local_flags
&= ~LOCAL_ADD_USER
;
138 * We are root - just write the new password
139 * and the valid last change time.
142 if(local_flags
& LOCAL_DISABLE_USER
) {
143 smb_pwent
->acct_ctrl
|= ACB_DISABLED
;
144 } else if (local_flags
& LOCAL_ENABLE_USER
) {
145 if(smb_pwent
->smb_passwd
== NULL
) {
146 smb_pwent
->smb_passwd
= new_p16
;
147 smb_pwent
->smb_nt_passwd
= new_nt_p16
;
149 smb_pwent
->acct_ctrl
&= ~ACB_DISABLED
;
150 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
151 smb_pwent
->acct_ctrl
|= ACB_PWNOTREQ
;
152 /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
153 smb_pwent
->smb_passwd
= NULL
;
154 smb_pwent
->smb_nt_passwd
= NULL
;
157 * If we're dealing with setting a completely empty user account
158 * ie. One with a password of 'XXXX', but not set disabled (like
159 * an account created from scratch) then if the old password was
160 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
161 * We remove that as we're giving this user their first password
162 * and the decision hasn't really been made to disable them (ie.
163 * don't create them disabled). JRA.
165 if((smb_pwent
->smb_passwd
== NULL
) && (smb_pwent
->acct_ctrl
& ACB_DISABLED
))
166 smb_pwent
->acct_ctrl
&= ~ACB_DISABLED
;
167 smb_pwent
->acct_ctrl
&= ~ACB_PWNOTREQ
;
168 smb_pwent
->smb_passwd
= new_p16
;
169 smb_pwent
->smb_nt_passwd
= new_nt_p16
;
172 if(local_flags
& LOCAL_DELETE_USER
) {
173 if (del_smbpwd_entry(user_name
)==False
) {
174 slprintf(err_str
,err_str_len
-1, "Failed to delete entry for user %s.\n", user_name
);
178 slprintf(msg_str
, msg_str_len
-1, "Deleted user %s.\n", user_name
);
180 if(mod_smbpwd_entry(smb_pwent
,True
) == False
) {
181 slprintf(err_str
, err_str_len
-1, "Failed to modify entry for user %s.\n", user_name
);
185 if(local_flags
& LOCAL_DISABLE_USER
)
186 slprintf(msg_str
, msg_str_len
-1, "Disabled user %s.\n", user_name
);
187 else if (local_flags
& LOCAL_ENABLE_USER
)
188 slprintf(msg_str
, msg_str_len
-1, "Enabled user %s.\n", user_name
);
189 else if (local_flags
& LOCAL_SET_NO_PASSWORD
)
190 slprintf(msg_str
, msg_str_len
-1, "User %s password set to none.\n", user_name
);