summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1998-11-12 07:06:48 +0000
committerAndrew Tridgell <tridge@samba.org>1998-11-12 07:06:48 +0000
commit29e36b713468d7e7de301c483fc340ef42b4a9fb (patch)
treefd97dcedea842356595ce290c2fb1f95d8448285 /source3/passdb
parent4f368d8b924b76007809e967ac1f37f6a1ebdd68 (diff)
downloadsamba-29e36b713468d7e7de301c483fc340ef42b4a9fb.tar.gz
samba-29e36b713468d7e7de301c483fc340ef42b4a9fb.tar.bz2
samba-29e36b713468d7e7de301c483fc340ef42b4a9fb.zip
extracted the password change code from smbpasswd and used it in swat
instead of opening pipes and other horrible stuff. (This used to be commit 49bf19710345a59a2d17cd449be1a132885ed821)
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;
+}
+