summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/smbpasschange.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/source3/passdb/smbpasschange.c b/source3/passdb/smbpasschange.c
new file mode 100644
index 0000000000..4e2813316e
--- /dev/null
+++ b/source3/passdb/smbpasschange.c
@@ -0,0 +1,162 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ change a password in a local smbpasswd file
+ Copyright (C) Andrew Tridgell 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+/*************************************************************
+add a new user to the local smbpasswd file
+*************************************************************/
+static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account,
+ BOOL disable_user, BOOL set_no_password,
+ uchar *new_p16, uchar *new_nt_p16)
+{
+ struct smb_passwd new_smb_pwent;
+
+ /* Create a new smb passwd entry and set it to the given password. */
+ new_smb_pwent.smb_userid = uid;
+ new_smb_pwent.smb_name = user_name;
+ new_smb_pwent.smb_passwd = NULL;
+ new_smb_pwent.smb_nt_passwd = NULL;
+ new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL);
+
+ if(disable_user) {
+ new_smb_pwent.acct_ctrl |= ACB_DISABLED;
+ } else if (set_no_password) {
+ new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
+ } else {
+ new_smb_pwent.smb_passwd = new_p16;
+ new_smb_pwent.smb_nt_passwd = new_nt_p16;
+ }
+
+ return add_smbpwd_entry(&new_smb_pwent);
+}
+
+
+/*************************************************************
+change a password entry in the local smbpasswd file
+*************************************************************/
+BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
+ BOOL enable_user, BOOL disable_user, BOOL set_no_password,
+ char *new_passwd)
+{
+ struct passwd *pwd;
+ void *vp;
+ struct smb_passwd *smb_pwent;
+ uchar new_p16[16];
+ uchar new_nt_p16[16];
+
+ pwd = getpwnam(user_name);
+
+ /*
+ * Check for a machine account.
+ */
+
+ if(trust_account && !pwd) {
+ fprintf(stderr, "User %s does not exist in system password file (usually /etc/passwd). Cannot add machine account without a valid system user.\n",
+ user_name);
+ return False;
+ }
+
+ /* Calculate the MD4 hash (NT compatible) of the new password. */
+ nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
+
+ /*
+ * Open the smbpaswd file.
+ */
+ vp = startsmbpwent(True);
+ if (!vp && errno == ENOENT) {
+ FILE *fp;
+ fprintf(stderr,"smbpasswd file did not exist - attempting to create it.\n");
+ fp = fopen(lp_smb_passwd_file(), "w");
+ if (fp) {
+ fprintf(fp, "# Samba SMB password file\n");
+ fclose(fp);
+ vp = startsmbpwent(True);
+ }
+ }
+
+ if (!vp) {
+ perror(lp_smb_passwd_file());
+ return False;
+ }
+
+ /* Get the smb passwd entry for this user */
+ smb_pwent = getsmbpwnam(user_name);
+ if (smb_pwent == NULL) {
+ if(add_user == False) {
+ fprintf(stderr, "Failed to find entry for user %s.\n",
+ pwd->pw_name);
+ endsmbpwent(vp);
+ return False;
+ }
+
+ if (add_new_user(user_name, pwd->pw_uid, trust_account, disable_user,
+ set_no_password, new_p16, new_nt_p16)) {
+ printf("Added user %s.\n", user_name);
+ endsmbpwent(vp);
+ return True;
+ } else {
+ fprintf(stderr, "Failed to add entry for user %s.\n", user_name);
+ endsmbpwent(vp);
+ return False;
+ }
+ } else {
+ /* the entry already existed */
+ add_user = False;
+ }
+
+ /*
+ * We are root - just write the new password
+ * and the valid last change time.
+ */
+
+ if(disable_user) {
+ smb_pwent->acct_ctrl |= ACB_DISABLED;
+ } else if (enable_user) {
+ if(smb_pwent->smb_passwd == NULL) {
+ smb_pwent->smb_passwd = new_p16;
+ smb_pwent->smb_nt_passwd = new_nt_p16;
+ }
+ smb_pwent->acct_ctrl &= ~ACB_DISABLED;
+ } else if (set_no_password) {
+ smb_pwent->acct_ctrl |= ACB_PWNOTREQ;
+ /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
+ smb_pwent->smb_passwd = NULL;
+ smb_pwent->smb_nt_passwd = NULL;
+ } else {
+ smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ;
+ smb_pwent->smb_passwd = new_p16;
+ smb_pwent->smb_nt_passwd = new_nt_p16;
+ }
+
+ if(mod_smbpwd_entry(smb_pwent,True) == False) {
+ fprintf(stderr, "Failed to modify entry for user %s.\n",
+ pwd->pw_name);
+ endsmbpwent(vp);
+ return False;
+ }
+
+ endsmbpwent(vp);
+
+ return True;
+}
+