Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / samba / source / passdb / smbpasschange.c
blob2c971fbff963e5d72a8a9ccc8137357c940c1c24
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
22 #include "includes.h"
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;
46 } else {
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,
61 char *new_passwd,
62 char *err_str, size_t err_str_len,
63 char *msg_str, size_t msg_str_len)
65 struct passwd *pwd = NULL;
66 void *vp;
67 struct smb_passwd *smb_pwent;
68 uchar new_p16[16];
69 uchar new_nt_p16[16];
71 *err_str = '\0';
72 *msg_str = '\0';
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);
84 return False;
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) {
96 FILE *fp;
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");
100 if (fp) {
101 fprintf(fp, "# Samba SMB password file\n");
102 fclose(fp);
103 vp = startsmbpwent(True);
107 if (!vp) {
108 slprintf(err_str, err_str_len-1, "Cannot open file %s. Error was %s\n",
109 lp_smb_passwd_file(), strerror(errno) );
110 return False;
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);
119 endsmbpwent(vp);
120 return False;
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);
125 endsmbpwent(vp);
126 return True;
127 } else {
128 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
129 endsmbpwent(vp);
130 return False;
132 } else {
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;
155 } else {
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);
175 endsmbpwent(vp);
176 return False;
178 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
179 } else {
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);
182 endsmbpwent(vp);
183 return False;
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);
193 endsmbpwent(vp);
195 return True;