This commit was manufactured by cvs2svn to create tag
[Samba.git] / source / passdb / smbpasschange.c
bloba0d9b1b143570f57418ebc3b402c0bae8e653323
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 *************************************************************/
28 static BOOL add_new_user(char *user_name, uid_t uid,
29 uint16 acb_info,
30 uchar *new_p16, uchar *new_nt_p16)
32 struct smb_passwd new_smb_pwent;
34 pwdb_init_smb(&new_smb_pwent);
36 /* Create a new smb passwd entry and set it to the given password. */
37 new_smb_pwent.unix_uid = uid;
38 new_smb_pwent.nt_name = user_name;
39 new_smb_pwent.smb_passwd = NULL;
40 new_smb_pwent.smb_nt_passwd = NULL;
41 new_smb_pwent.acct_ctrl = acb_info;
43 if (IS_BITS_CLR_ALL(acb_info, ACB_DISABLED | ACB_PWNOTREQ))
45 new_smb_pwent.smb_passwd = new_p16;
46 new_smb_pwent.smb_nt_passwd = new_nt_p16;
49 return add_smbpwd_entry(&new_smb_pwent);
53 /*************************************************************
54 change a password entry in the local smbpasswd file.
56 when modifying an account, set acb_mask to those bits that
57 require changing (to zero or one) and set acb_info to the
58 value required in those bits. all bits NOT set in acb_mask
59 will NOT be modified.
61 when _adding_ an account, acb_mask must be set to 0xFFFF and
62 it is ignored, btw :-)
64 *************************************************************/
65 BOOL local_password_change(char *user_name,
66 BOOL add_user,
67 uint16 acb_info, uint16 acb_mask,
68 char *new_passwd,
69 char *err_str, size_t err_str_len,
70 char *msg_str, size_t msg_str_len)
72 const struct passwd *pwd;
73 struct smb_passwd *smb_pwent;
74 static struct smb_passwd new_pwent;
75 static uchar new_p16[16];
76 static uchar new_nt_p16[16];
77 fstring unix_name;
78 uid_t unix_uid;
80 *err_str = '\0';
81 *msg_str = '\0';
83 pwd = Get_Pwnam(user_name, False);
86 * Check for a trust account.
89 if ((acb_info & acb_mask) != acb_info)
91 slprintf(err_str, err_str_len - 1, "programmer error: acb_info (%x) requests bits to be set outside of acb_mask (%x) range\n", acb_info, acb_mask);
94 if (pwd == NULL)
96 if (!IS_BITS_SET_ALL(acb_info, ACB_NORMAL))
98 slprintf(err_str, err_str_len - 1, "User %s does not \
99 exist in system password file (usually /etc/passwd). \
100 Cannot add trust account without a valid system user.\n", user_name);
102 else
104 slprintf(err_str, err_str_len - 1, "User %s does not \
105 exist in system password file (usually /etc/passwd).\n", user_name);
107 return False;
110 unix_uid = pwd->pw_uid;
111 fstrcpy(unix_name, pwd->pw_name);
113 /* Calculate the MD4 hash (NT compatible) of the new password. */
114 nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
116 /* Get the smb passwd entry for this user */
117 smb_pwent = getsmbpwnam(user_name);
118 if (smb_pwent == NULL)
120 if (!add_user)
122 slprintf(err_str, err_str_len-1,
123 "Failed to find entry for user %s.\n", unix_name);
124 return False;
127 if (add_new_user(user_name, unix_uid, acb_info,
128 new_p16, new_nt_p16))
130 slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
131 return True;
133 else
135 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
136 return False;
139 else
141 /* the entry already existed */
142 add_user = False;
146 * We are root - just write the new password
147 * and the valid last change time.
150 memcpy(&new_pwent, smb_pwent, sizeof(new_pwent));
151 new_pwent.nt_name = user_name;
152 new_pwent.acct_ctrl &= ~acb_mask;
153 new_pwent.acct_ctrl |= (acb_info & acb_mask);
154 new_pwent.smb_passwd = NULL;
155 new_pwent.smb_nt_passwd = NULL;
157 if (IS_BITS_CLR_ALL(acb_info, ACB_DISABLED | ACB_PWNOTREQ))
159 new_pwent.smb_passwd = new_p16;
160 new_pwent.smb_nt_passwd = new_nt_p16;
163 if (!mod_smbpwd_entry(&new_pwent, True))
165 slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n",
166 unix_name);
167 return False;
170 return True;