Beispiel #1
0
static int delete_user_entry(const char *username)
{
	struct samu *samaccount;

	samaccount = samu_new(NULL);
	if (!samaccount) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (!pdb_getsampwnam(samaccount, username)) {
		fprintf (stderr,
			 "user %s does not exist in the passdb\n", username);
		TALLOC_FREE(samaccount);
		return -1;
	}

	if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
		fprintf (stderr, "Unable to delete user %s\n", username);
		TALLOC_FREE(samaccount);
		return -1;
	}

	TALLOC_FREE(samaccount);
	return 0;
}
Beispiel #2
0
static BOOL get_md4pw(char *md4pw, char *mach_acct)
{
	SAM_ACCOUNT *sampass = NULL;
	const uint8 *pass;
	BOOL ret;
	uint32 acct_ctrl;

#if 0
    /*
     * Currently this code is redundent as we already have a filter
     * by hostname list. What this code really needs to do is to 
     * get a hosts allowed/hosts denied list from the SAM database
     * on a per user basis, and make the access decision there.
     * I will leave this code here for now as a reminder to implement
     * this at a later date. JRA.
     */

	if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
	                  client_name(), client_addr()))
	{
		DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
		return False;
	}
#endif /* 0 */

	if(!NT_STATUS_IS_OK(pdb_init_sam(&sampass)))
		return False;

	/* JRA. This is ok as it is only used for generating the challenge. */
	become_root();
	ret=pdb_getsampwnam(sampass, mach_acct);
	unbecome_root();
 
 	if (ret==False) {
 		DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
		pdb_free_sam(&sampass);
		return False;
	}

	acct_ctrl = pdb_get_acct_ctrl(sampass);
	if (!(acct_ctrl & ACB_DISABLED) &&
	    ((acct_ctrl & ACB_DOMTRUST) ||
	     (acct_ctrl & ACB_WSTRUST) ||
	     (acct_ctrl & ACB_SVRTRUST)) &&
	    ((pass=pdb_get_nt_passwd(sampass)) != NULL)) {
		memcpy(md4pw, pass, 16);
		dump_data(5, md4pw, 16);
 		pdb_free_sam(&sampass);
		return True;
	}
 	
	DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
	pdb_free_sam(&sampass);
	return False;

}
Beispiel #3
0
/**
 * update the encrypted smbpasswd file from the plaintext username and password
 *
 *  this ugly hack needs to die, but not quite yet, I think people still use it...
 **/
static BOOL update_smbpassword_file(const char *user, const char *password)
{
    struct samu 	*sampass;
    BOOL            ret;

    if ( !(sampass = samu_new( NULL )) ) {
        return False;
    }

    become_root();
    ret = pdb_getsampwnam(sampass, user);
    unbecome_root();

    if(ret == False) {
        DEBUG(0,("pdb_getsampwnam returned NULL\n"));
        TALLOC_FREE(sampass);
        return False;
    }

    /*
     * Remove the account disabled flag - we are updating the
     * users password from a login.
     */
    if (!pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED, PDB_CHANGED)) {
        TALLOC_FREE(sampass);
        return False;
    }

    if (!pdb_set_plaintext_passwd (sampass, password)) {
        TALLOC_FREE(sampass);
        return False;
    }

    /* Now write it into the file. */
    become_root();

    ret = NT_STATUS_IS_OK(pdb_update_sam_account (sampass));

    unbecome_root();

    if (ret) {
        DEBUG(3,("pdb_update_sam_account returned %d\n",ret));
    }

    TALLOC_FREE(sampass);
    return ret;
}
Beispiel #4
0
static int delete_machine_entry(const char *machinename)
{
	struct samu *samaccount = NULL;
	const char *name;

	if (strlen(machinename) == 0) {
		fprintf(stderr, "No machine name given\n");
		return -1;
	}

	samaccount = samu_new(NULL);
	if (!samaccount) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (machinename[strlen(machinename)-1] != '$') {
		name = talloc_asprintf(samaccount, "%s$", machinename);
	} else {
		name = machinename;
	}

	if (!pdb_getsampwnam(samaccount, name)) {
		fprintf (stderr,
			 "machine %s does not exist in the passdb\n", name);
		TALLOC_FREE(samaccount);
		return -1;
	}

	if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
		fprintf (stderr, "Unable to delete machine %s\n", name);
		TALLOC_FREE(samaccount);
		return -1;
	}

	TALLOC_FREE(samaccount);
	return 0;
}
Beispiel #5
0
/*******************************************************************
 Look up a local user name and return a rid
 ********************************************************************/
NTSTATUS local_lookup_user_rid(char *user_name, uint32 *rid)
{
	SAM_ACCOUNT *sampass=NULL;
	BOOL ret;

	(*rid) = 0;

	pdb_init_sam(&sampass);

	/* find the user account */
	become_root();
	ret = pdb_getsampwnam(sampass, user_name);
	unbecome_root();

	if (ret == True) {
		(*rid) = pdb_get_user_rid(sampass);
		pdb_free_sam(&sampass);
		return NT_STATUS_OK;
	}

	pdb_free_sam(&sampass);
	return NT_STATUS_NONE_MAPPED;
}
Beispiel #6
0
static int print_user_info(const char *username,
			   bool verbosity, bool smbpwdstyle)
{
	struct samu *sam_pwent = NULL;
	bool bret;
	int ret;

	sam_pwent = samu_new(NULL);
	if (!sam_pwent) {
		return -1;
	}

	bret = pdb_getsampwnam(sam_pwent, username);
	if (!bret) {
		fprintf (stderr, "Username not found!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	ret = print_sam_info(sam_pwent, verbosity, smbpwdstyle);

	TALLOC_FREE(sam_pwent);
	return ret;
}
Beispiel #7
0
static int set_machine_info(const char *machinename,
			    const char *account_control,
			    const char *machine_sid)
{
	struct samu *sam_pwent = NULL;
	TALLOC_CTX *tosctx;
	uint32_t acb_flags;
	uint32_t not_settable;
	uint32_t new_flags;
	struct dom_sid m_sid;
	char *name;
	int len;
	bool ret;

	len = strlen(machinename);
	if (len == 0) {
		fprintf(stderr, "No machine name given\n");
		return -1;
	}

	tosctx = talloc_tos();
	if (!tosctx) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	sam_pwent = samu_new(tosctx);
	if (!sam_pwent) {
		return 1;
	}

	if (machinename[len-1] == '$') {
		name = talloc_strdup(sam_pwent, machinename);
	} else {
		name = talloc_asprintf(sam_pwent, "%s$", machinename);
	}
	if (!name) {
		fprintf(stderr, "Out of memory!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	if (!strlower_m(name)) {
		fprintf(stderr, "strlower_m %s failed\n", name);
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	ret = pdb_getsampwnam(sam_pwent, name);
	if (!ret) {
		fprintf (stderr, "Username not found!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	if (account_control) {
		not_settable = ~(ACB_DISABLED);

		new_flags = pdb_decode_acct_ctrl(account_control);

		if (new_flags & not_settable) {
			fprintf(stderr, "Can only set [D] flags\n");
			TALLOC_FREE(sam_pwent);
			return -1;
		}

		acb_flags = pdb_get_acct_ctrl(sam_pwent);

		pdb_set_acct_ctrl(sam_pwent,
				  (acb_flags & not_settable) | new_flags,
				  PDB_CHANGED);
	}
	if (machine_sid) {
		if (get_sid_from_cli_string(&m_sid, machine_sid)) {
			fprintf(stderr, "Failed to parse SID\n");
			return -1;
		}
		pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);
	}

	if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
		print_user_info(name, True, False);
	} else {
		fprintf (stderr, "Unable to modify entry!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}
	TALLOC_FREE(sam_pwent);
	return 0;
}
Beispiel #8
0
static int set_user_info(const char *username, const char *fullname,
			 const char *homedir, const char *acct_desc,
			 const char *drive, const char *script,
			 const char *profile, const char *account_control,
			 const char *user_sid, const char *user_domain,
			 const bool badpw, const bool hours,
			 const char *kickoff_time)
{
	bool updated_autolock = False, updated_badpw = False;
	struct samu *sam_pwent;
	uint8_t hours_array[MAX_HOURS_LEN];
	uint32_t hours_len;
	uint32_t acb_flags;
	uint32_t not_settable;
	uint32_t new_flags;
	struct dom_sid u_sid;
	bool ret;

	sam_pwent = samu_new(NULL);
	if (!sam_pwent) {
		return 1;
	}

	ret = pdb_getsampwnam(sam_pwent, username);
	if (!ret) {
		fprintf (stderr, "Username not found!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	if (hours) {
		hours_len = pdb_get_hours_len(sam_pwent);
		memset(hours_array, 0xff, hours_len);

		pdb_set_hours(sam_pwent, hours_array, hours_len, PDB_CHANGED);
	}

	if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
		DEBUG(2,("pdb_update_autolock_flag failed.\n"));
	}

	if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw)) {
		DEBUG(2,("pdb_update_bad_password_count failed.\n"));
	}

	if (fullname)
		pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
	if (acct_desc)
		pdb_set_acct_desc(sam_pwent, acct_desc, PDB_CHANGED);
	if (homedir)
		pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
	if (drive)
		pdb_set_dir_drive(sam_pwent,drive, PDB_CHANGED);
	if (script)
		pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
	if (profile)
		pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
	if (user_domain)
		pdb_set_domain(sam_pwent, user_domain, PDB_CHANGED);

	if (account_control) {
		not_settable = ~(ACB_DISABLED | ACB_HOMDIRREQ |
				 ACB_PWNOTREQ | ACB_PWNOEXP | ACB_AUTOLOCK);

		new_flags = pdb_decode_acct_ctrl(account_control);

		if (new_flags & not_settable) {
			fprintf(stderr, "Can only set [NDHLX] flags\n");
			TALLOC_FREE(sam_pwent);
			return -1;
		}

		acb_flags = pdb_get_acct_ctrl(sam_pwent);

		pdb_set_acct_ctrl(sam_pwent,
				  (acb_flags & not_settable) | new_flags,
				  PDB_CHANGED);
	}
	if (user_sid) {
		if (get_sid_from_cli_string(&u_sid, user_sid)) {
			fprintf(stderr, "Failed to parse SID\n");
			return -1;
		}
		pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);
	}

	if (badpw) {
		pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED);
		pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
	}

	if (kickoff_time) {
		char *endptr;
		time_t value = get_time_t_max();

		if (strcmp(kickoff_time, "never") != 0) {
			uint32_t num = strtoul(kickoff_time, &endptr, 10);

			if ((endptr == kickoff_time) || (endptr[0] != '\0')) {
				fprintf(stderr, "Failed to parse kickoff time\n");
				return -1;
			}

			value = convert_uint32_t_to_time_t(num);
		}

		pdb_set_kickoff_time(sam_pwent, value, PDB_CHANGED);
	}

	if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
		print_user_info(username, True, False);
	} else {
		fprintf (stderr, "Unable to modify entry!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}
	TALLOC_FREE(sam_pwent);
	return 0;
}
Beispiel #9
0
int pam_sm_authenticate(pam_handle_t *pamh, int flags,
                        int argc, const char **argv)
{
	unsigned int ctrl;
	int retval, *ret_data = NULL;
	struct samu *sampass = NULL;
	const char *name;
	void (*oldsig_handler)(int) = NULL;
	bool found;

	/* Points to memory managed by the PAM library. Do not free. */
	char *p = NULL;

	/* Samba initialization. */
	load_case_tables();
        lp_set_in_client(True);

	ctrl = set_ctrl(pamh, flags, argc, argv);

	/* Get a few bytes so we can pass our return value to
		pam_sm_setcred(). */
	ret_data = SMB_MALLOC_P(int);

	/* we need to do this before we call AUTH_RETURN */
	/* Getting into places that might use LDAP -- protect the app
	from a SIGPIPE it's not expecting */
	oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);

	/* get the username */
	retval = pam_get_user( pamh, &name, "Username: "******"auth: could not identify user");
		}
		AUTH_RETURN;
	}
	if (on( SMB_DEBUG, ctrl )) {
		_log_err(pamh, LOG_DEBUG, "username [%s] obtained", name );
	}

	if (geteuid() != 0) {
		_log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root.");
		retval = PAM_AUTHINFO_UNAVAIL;
		AUTH_RETURN;
	}

	if (!initialize_password_db(True, NULL)) {
		_log_err(pamh, LOG_ALERT, "Cannot access samba password database" );
		retval = PAM_AUTHINFO_UNAVAIL;
		AUTH_RETURN;
	}

	sampass = samu_new( NULL );
    	if (!sampass) {
		_log_err(pamh, LOG_ALERT, "Cannot talloc a samu struct" );
		retval = nt_status_to_pam(NT_STATUS_NO_MEMORY);
		AUTH_RETURN;
	}

	found = pdb_getsampwnam( sampass, name );

	if (on( SMB_MIGRATE, ctrl )) {
		retval = _smb_add_user(pamh, ctrl, name, sampass, found);
		TALLOC_FREE(sampass);
		AUTH_RETURN;
	}

	if (!found) {
		_log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", name);
		retval = PAM_USER_UNKNOWN;
		TALLOC_FREE(sampass);
		sampass = NULL;
		AUTH_RETURN;
	}

	/* if this user does not have a password... */

	if (_smb_blankpasswd( ctrl, sampass )) {
		TALLOC_FREE(sampass);
		retval = PAM_SUCCESS;
		AUTH_RETURN;
	}

	/* get this user's authentication token */

	retval = _smb_read_password(pamh, ctrl, NULL, "Password: "******"auth: no password provided for [%s]", name);
		TALLOC_FREE(sampass);
		AUTH_RETURN;
	}

	/* verify the password of this user */

	retval = _smb_verify_password( pamh, sampass, p, ctrl );
	TALLOC_FREE(sampass);
	p = NULL;
	AUTH_RETURN;
}
Beispiel #10
0
NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
				char *ntuser,
				char *ntdomain,
				char *username,
				struct passwd *pw,
				struct PAC_LOGON_INFO *logon_info,
				bool mapped_to_guest, bool username_was_mapped,
				DATA_BLOB *session_key,
				struct auth_session_info **session_info)
{
	NTSTATUS status;
	struct auth_serversupplied_info *server_info;

	if (mapped_to_guest) {
		status = make_server_info_guest(mem_ctx, &server_info);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("make_server_info_guest failed: %s!\n",
				  nt_errstr(status)));
			return status;
		}

	} else if (logon_info) {
		/* pass the unmapped username here since map_username()
		   will be called again in make_server_info_info3() */

		status = make_server_info_info3(mem_ctx,
						ntuser, ntdomain,
						&server_info,
						&logon_info->info3);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("make_server_info_info3 failed: %s!\n",
				  nt_errstr(status)));
			return status;
		}

	} else {
		/*
		 * We didn't get a PAC, we have to make up the user
		 * ourselves. Try to ask the pdb backend to provide
		 * SID consistency with ntlmssp session setup
		 */
		struct samu *sampass;
		/* The stupid make_server_info_XX functions here
		   don't take a talloc context. */
		struct auth_serversupplied_info *tmp = NULL;

		sampass = samu_new(talloc_tos());
		if (sampass == NULL) {
			return NT_STATUS_NO_MEMORY;
		}

		if (pdb_getsampwnam(sampass, username)) {
			DEBUG(10, ("found user %s in passdb, calling "
				   "make_server_info_sam\n", username));
			status = make_server_info_sam(&tmp, sampass);
		} else {
			/*
			 * User not in passdb, make it up artificially
			 */
			DEBUG(10, ("didn't find user %s in passdb, calling "
				   "make_server_info_pw\n", username));
			status = make_server_info_pw(&tmp, username, pw);
		}
		TALLOC_FREE(sampass);

		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("make_server_info_[sam|pw] failed: %s!\n",
				  nt_errstr(status)));
			return status;
                }

		/* make_server_info_pw does not set the domain. Without this
		 * we end up with the local netbios name in substitutions for
		 * %D. */

		if (server_info->info3 != NULL) {
			server_info->info3->base.domain.string =
				talloc_strdup(server_info->info3, ntdomain);
		}
	}

	server_info->nss_token |= username_was_mapped;

	status = create_local_token(mem_ctx, server_info, session_key, ntuser, session_info);
	talloc_free(server_info);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10,("failed to create local token: %s\n",
			  nt_errstr(status)));
		return status;
	}

	return NT_STATUS_OK;
}
Beispiel #11
0
int pam_sm_authenticate(pam_handle_t *pamh, int flags,
                        int argc, const char **argv)
{
    unsigned int ctrl;
    int retval, *ret_data = NULL;
    SAM_ACCOUNT *sampass = NULL;
    extern BOOL in_client;
    const char *name;
    void (*oldsig_handler)(int);
    BOOL found;

    /* Points to memory managed by the PAM library. Do not free. */
    char *p = NULL;


    /* Samba initialization. */
    setup_logging("pam_smbpass",False);
    in_client = True;

    ctrl = set_ctrl(flags, argc, argv);

    /* Get a few bytes so we can pass our return value to
       pam_sm_setcred(). */
    ret_data = malloc(sizeof(int));

    /* get the username */
    retval = pam_get_user( pamh, &name, "Username: "******"auth: could not identify user");
        }
        AUTH_RETURN;
    }
    if (on( SMB_DEBUG, ctrl )) {
        _log_err( LOG_DEBUG, "username [%s] obtained", name );
    }

    /* Getting into places that might use LDAP -- protect the app
       from a SIGPIPE it's not expecting */
    oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);

    if (!initialize_password_db(True)) {
        _log_err( LOG_ALERT, "Cannot access samba password database" );
        retval = PAM_AUTHINFO_UNAVAIL;
        AUTH_RETURN;
    }

    pdb_init_sam(&sampass);
    
    found = pdb_getsampwnam( sampass, name );

    if (on( SMB_MIGRATE, ctrl )) {
	retval = _smb_add_user(pamh, ctrl, name, sampass, found);
	pdb_free_sam(&sampass);
	AUTH_RETURN;
    }

    if (!found) {
        _log_err(LOG_ALERT, "Failed to find entry for user %s.", name);
        retval = PAM_USER_UNKNOWN;
	pdb_free_sam(&sampass);
	sampass = NULL;
        AUTH_RETURN;
    }
   
    /* if this user does not have a password... */

    if (_smb_blankpasswd( ctrl, sampass )) {
        pdb_free_sam(&sampass);
        retval = PAM_SUCCESS;
        AUTH_RETURN;
    }

    /* get this user's authentication token */

    retval = _smb_read_password(pamh, ctrl, NULL, "Password: "******"auth: no password provided for [%s]"
		 , name);
        pdb_free_sam(&sampass);
        AUTH_RETURN;
    }

    /* verify the password of this user */

    retval = _smb_verify_password( pamh, sampass, p, ctrl );
    pdb_free_sam(&sampass);
    p = NULL;
    AUTH_RETURN;
}
Beispiel #12
0
int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
                     int argc, const char **argv)
{
    unsigned int ctrl;
    int retval;

    extern BOOL in_client;

    SAM_ACCOUNT *sampass = NULL;
    void (*oldsig_handler)(int);
    const char *user;
    char *pass_old;
    char *pass_new;

    NTSTATUS nt_status;

    /* Samba initialization. */
    setup_logging( "pam_smbpass", False );
    in_client = True;

    ctrl = set_ctrl(flags, argc, argv);

    /*
     * First get the name of a user.  No need to do anything if we can't
     * determine this.
     */

    retval = pam_get_user( pamh, &user, "Username: "******"password: could not identify user" );
        }
        return retval;
    }
    if (on( SMB_DEBUG, ctrl )) {
        _log_err( LOG_DEBUG, "username [%s] obtained", user );
    }

    /* Getting into places that might use LDAP -- protect the app
       from a SIGPIPE it's not expecting */
    oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);

    if (!initialize_password_db(True)) {
        _log_err( LOG_ALERT, "Cannot access samba password database" );
        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        return PAM_AUTHINFO_UNAVAIL;
    }

    /* obtain user record */
    if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {
        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        return nt_status_to_pam(nt_status);
    }

    if (!pdb_getsampwnam(sampass,user)) {
        _log_err( LOG_ALERT, "Failed to find entry for user %s.", user );
        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        return PAM_USER_UNKNOWN;
    }

    if (flags & PAM_PRELIM_CHECK) {
        /*
         * obtain and verify the current password (OLDAUTHTOK) for
         * the user.
         */

        char *Announce;

        if (_smb_blankpasswd( ctrl, sampass )) {

            pdb_free_sam(&sampass);
            CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
            return PAM_SUCCESS;
        }

	/* Password change by root, or for an expired token, doesn't
           require authentication.  Is this a good choice? */
        if (getuid() != 0 && !(flags & PAM_CHANGE_EXPIRED_AUTHTOK)) {

            /* tell user what is happening */
#define greeting "Changing password for "
            Announce = (char *) malloc(sizeof(greeting)+strlen(user));
            if (Announce == NULL) {
                _log_err(LOG_CRIT, "password: out of memory");
                pdb_free_sam(&sampass);
                CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
                return PAM_BUF_ERR;
            }
            strncpy( Announce, greeting, sizeof(greeting) );
            strncpy( Announce+sizeof(greeting)-1, user, strlen(user)+1 );
#undef greeting

            set( SMB__OLD_PASSWD, ctrl );
            retval = _smb_read_password( pamh, ctrl, Announce, "Current SMB password: "******"password - (old) token not obtained" );
                pdb_free_sam(&sampass);
                CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
                return retval;
            }

            /* verify that this is the password for this user */

            retval = _smb_verify_password( pamh, sampass, pass_old, ctrl );

        } else {
	    pass_old = NULL;
            retval = PAM_SUCCESS;           /* root doesn't have to */
        }

        pass_old = NULL;
        pdb_free_sam(&sampass);
        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        return retval;

    } else if (flags & PAM_UPDATE_AUTHTOK) {

        /*
         * obtain the proposed password
         */

        /*
         * get the old token back. NULL was ok only if root [at this
         * point we assume that this has already been enforced on a
         * previous call to this function].
         */

        if (off( SMB_NOT_SET_PASS, ctrl )) {
            retval = pam_get_item( pamh, PAM_OLDAUTHTOK,
                                   (const void **)&pass_old );
        } else {
            retval = pam_get_data( pamh, _SMB_OLD_AUTHTOK,
                                   (const void **)&pass_old );
            if (retval == PAM_NO_MODULE_DATA) {
		pass_old = NULL;
                retval = PAM_SUCCESS;
            }
        }

        if (retval != PAM_SUCCESS) {
            _log_err( LOG_NOTICE, "password: user not authenticated" );
            pdb_free_sam(&sampass);
            CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
            return retval;
        }

        /*
         * use_authtok is to force the use of a previously entered
         * password -- needed for pluggable password strength checking
	 * or other module stacking
         */

        if (on( SMB_USE_AUTHTOK, ctrl )) {
            set( SMB_USE_FIRST_PASS, ctrl );
        }

        retval = _smb_read_password( pamh, ctrl
                                      , NULL
                                      , "Enter new SMB password: "******"Retype new SMB password: "******"password: new password not obtained" );
            }
            pass_old = NULL;                               /* tidy up */
            pdb_free_sam(&sampass);
            CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
            return retval;
        }

        /*
         * At this point we know who the user is and what they
         * propose as their new password. Verify that the new
         * password is acceptable.
         */ 

        if (pass_new[0] == '\0') {     /* "\0" password = NULL */
            pass_new = NULL;
        }

        retval = _pam_smb_approve_pass(pamh, ctrl, pass_old, pass_new);

        if (retval != PAM_SUCCESS) {
            _log_err(LOG_NOTICE, "new password not acceptable");
            pass_new = pass_old = NULL;               /* tidy up */
            pdb_free_sam(&sampass);
            CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
            return retval;
        }

        /*
         * By reaching here we have approved the passwords and must now
         * rebuild the smb password file.
         */

        /* update the password database */

        retval = smb_update_db(pamh, ctrl, user, pass_new);
        if (retval == PAM_SUCCESS) {
	    uid_t uid;
	    
            /* password updated */
		if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sampass), &uid))) {
			_log_err( LOG_NOTICE, "Unable to get uid for user %s",
				pdb_get_username(sampass));
			_log_err( LOG_NOTICE, "password for (%s) changed by (%s/%d)",
				user, uidtoname(getuid()), getuid());
		} else {
			_log_err( LOG_NOTICE, "password for (%s/%d) changed by (%s/%d)",
				user, uid, uidtoname(getuid()), getuid());
		}
	} else {
		_log_err( LOG_ERR, "password change failed for user %s", user);
	}

        pass_old = pass_new = NULL;
	if (sampass) {
		pdb_free_sam(&sampass);
		sampass = NULL;
	}

    } else {            /* something has broken with the library */

        _log_err( LOG_ALERT, "password received unknown request" );
        retval = PAM_ABORT;

    }
    
    if (sampass) {
    	pdb_free_sam(&sampass);
	sampass = NULL;
    }

    pdb_free_sam(&sampass);
    CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
    return retval;
}
Beispiel #13
0
int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
                      int argc, const char **argv )
{
    unsigned int ctrl;
    int retval;

    const char *name;
    SAM_ACCOUNT *sampass = NULL;
    void (*oldsig_handler)(int);
    extern BOOL in_client;

    /* Samba initialization. */
    setup_logging( "pam_smbpass", False );
    in_client = True;

    ctrl = set_ctrl( flags, argc, argv );

    /* get the username */

    retval = pam_get_user( pamh, &name, "Username: "******"acct: could not identify user" );
        }
        return retval;
    }
    if (on( SMB_DEBUG, ctrl )) {
        _log_err( LOG_DEBUG, "acct: username [%s] obtained", name );
    }

    /* Getting into places that might use LDAP -- protect the app
       from a SIGPIPE it's not expecting */
    oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
    if (!initialize_password_db(True)) {
        _log_err( LOG_ALERT, "Cannot access samba password database" );
        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        return PAM_AUTHINFO_UNAVAIL;
    }

    /* Get the user's record. */
    pdb_init_sam(&sampass);
    pdb_getsampwnam(sampass, name );

    if (!sampass) {
        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        return PAM_USER_UNKNOWN;
    }

    if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
        if (on( SMB_DEBUG, ctrl )) {
            _log_err( LOG_DEBUG
                      , "acct: account %s is administratively disabled", name );
        }
        make_remark( pamh, ctrl, PAM_ERROR_MSG
                     , "Your account has been disabled; "
                       "please see your system administrator." );

        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        return PAM_ACCT_EXPIRED;
    }

    /* TODO: support for expired passwords. */

    CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
    return PAM_SUCCESS;
}
Beispiel #14
0
static int process_root(int local_flags)
{
	struct passwd  *pwd;
	int result = 0;
	char *old_passwd = NULL;

	if (local_flags & LOCAL_SET_LDAP_ADMIN_PW) {
		char *ldap_admin_dn = lp_ldap_admin_dn();
		if ( ! *ldap_admin_dn ) {
			DEBUG(0,("ERROR: 'ldap admin dn' not defined! Please check your smb.conf\n"));
			goto done;
		}

		printf("Setting stored password for \"%s\" in secrets.tdb\n", ldap_admin_dn);
		if ( ! *ldap_secret ) {
			new_passwd = prompt_for_new_password(stdin_passwd_get);
			fstrcpy(ldap_secret, new_passwd);
		}
		if (!store_ldap_admin_pw(ldap_secret)) {
			DEBUG(0,("ERROR: Failed to store the ldap admin password!\n"));
		}
		goto done;
	}

	/* Ensure passdb startup(). */
	if(!initialize_password_db(False)) {
		DEBUG(0, ("Failed to open passdb!\n"));
		exit(1);
	}
		
	/* Ensure we have a SAM sid. */
	get_global_sam_sid();

	/*
	 * Ensure both add/delete user are not set
	 * Ensure add/delete user and either remote machine or join domain are
	 * not both set.
	 */	
	if(((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) == (LOCAL_ADD_USER|LOCAL_DELETE_USER)) || 
	   ((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) && 
		(remote_machine != NULL))) {
		usage();
	}
	
	/* Only load interfaces if we are doing network operations. */

	if (remote_machine) {
		load_interfaces();
	}

	if (!user_name[0] && (pwd = getpwuid_alloc(NULL, geteuid()))) {
		fstrcpy(user_name, pwd->pw_name);
		TALLOC_FREE(pwd);
	} 

	if (!user_name[0]) {
		fprintf(stderr,"You must specify a username\n");
		exit(1);
	}

	if (local_flags & LOCAL_TRUST_ACCOUNT) {
		/* add the $ automatically */
		static fstring buf;

		/*
		 * Remove any trailing '$' before we
		 * generate the initial machine password.
		 */

		if (user_name[strlen(user_name)-1] == '$') {
			user_name[strlen(user_name)-1] = 0;
		}

		if (local_flags & LOCAL_ADD_USER) {
		        SAFE_FREE(new_passwd);
			new_passwd = smb_xstrdup(user_name);
			strlower_m(new_passwd);
		}

		/*
		 * Now ensure the username ends in '$' for
		 * the machine add.
		 */

		slprintf(buf, sizeof(buf)-1, "%s$", user_name);
		fstrcpy(user_name, buf);
	} else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
		static fstring buf;

		if ((local_flags & LOCAL_ADD_USER) && (new_passwd == NULL)) {
			/*
			 * Prompt for trusting domain's account password
			 */
			new_passwd = prompt_for_new_password(stdin_passwd_get);
			if(!new_passwd) {
				fprintf(stderr, "Unable to get newpassword.\n");
				exit(1);
			}
		}
		
		/* prepare uppercased and '$' terminated username */
		slprintf(buf, sizeof(buf) - 1, "%s$", user_name);
		fstrcpy(user_name, buf);
		
	} else {
		
		if (remote_machine != NULL) {
			old_passwd = get_pass("Old SMB password:"******"talloc fail for struct samu.\n");
					exit(1);
				}
				if (!pdb_getsampwnam(sampass, user_name)) {
					fprintf(stderr, "Failed to find user %s in passdb backend.\n",
						user_name );
					exit(1);
				}

				if(pdb_get_nt_passwd(sampass) == NULL) {
					local_flags |= LOCAL_SET_PASSWORD;
				}
				TALLOC_FREE(sampass);
			}
		}
		
		if((local_flags & LOCAL_SET_PASSWORD) && (new_passwd == NULL)) {
			new_passwd = prompt_for_new_password(stdin_passwd_get);
			
			if(!new_passwd) {
				fprintf(stderr, "Unable to get new password.\n");
				exit(1);
			}
		}
	}

	if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name,
					     old_passwd, new_passwd,
					     local_flags))) {
		fprintf(stderr,"Failed to modify password entry for user %s\n", user_name);
		result = 1;
		goto done;
	} 

	if(remote_machine) {
		printf("Password changed for user %s on %s.\n", user_name, remote_machine );
	} else if(!(local_flags & (LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|LOCAL_DELETE_USER|LOCAL_SET_NO_PASSWORD|LOCAL_SET_PASSWORD))) {
		struct samu *sampass = NULL;
		
		sampass = samu_new( NULL );
		if (!sampass) {
			fprintf(stderr, "talloc fail for struct samu.\n");
			exit(1);
		}

		if (!pdb_getsampwnam(sampass, user_name)) {
			fprintf(stderr, "Failed to find user %s in passdb backend.\n",
				user_name );
			exit(1);
		}

		printf("Password changed for user %s.", user_name );
		if(pdb_get_acct_ctrl(sampass)&ACB_DISABLED) {
			printf(" User has disabled flag set.");
		}
		if(pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ) {
			printf(" User has no password flag set.");
		}
		printf("\n");
		TALLOC_FREE(sampass);
	}

 done:
	SAFE_FREE(new_passwd);
	return result;
}
Beispiel #15
0
NTSTATUS check_sam_security(const DATA_BLOB *challenge,
			    TALLOC_CTX *mem_ctx,
			    const struct auth_usersupplied_info *user_info,
			    struct auth_serversupplied_info **server_info)
{
	struct samu *sampass=NULL;
	bool ret;
	NTSTATUS nt_status;
	NTSTATUS update_login_attempts_status;
	DATA_BLOB user_sess_key = data_blob_null;
	DATA_BLOB lm_sess_key = data_blob_null;
	bool updated_badpw = False;
	const char *username;
	const uint8_t *nt_pw;
	const uint8_t *lm_pw;
	uint32_t acct_ctrl;

	/* the returned struct gets kept on the server_info, by means
	   of a steal further down */

	sampass = samu_new(mem_ctx);
	if (sampass == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	/* get the account information */

	become_root();
	ret = pdb_getsampwnam(sampass, user_info->mapped.account_name);
	unbecome_root();

	if (ret == False) {
		DEBUG(3,("check_sam_security: Couldn't find user '%s' in "
			 "passdb.\n", user_info->mapped.account_name));
		TALLOC_FREE(sampass);
		return NT_STATUS_NO_SUCH_USER;
	}

	acct_ctrl = pdb_get_acct_ctrl(sampass);
	username = pdb_get_username(sampass);
	nt_pw = pdb_get_nt_passwd(sampass);
	lm_pw = pdb_get_lanman_passwd(sampass);

	/* Quit if the account was locked out. */
	if (acct_ctrl & ACB_AUTOLOCK) {
		DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", username));
		TALLOC_FREE(sampass);
		return NT_STATUS_ACCOUNT_LOCKED_OUT;
	}

	nt_status = sam_password_ok(mem_ctx,
				    username, acct_ctrl,
				    challenge, lm_pw, nt_pw,
				    user_info, &user_sess_key, &lm_sess_key);

	/* Notify passdb backend of login success/failure. If not
	   NT_STATUS_OK the backend doesn't like the login */

	update_login_attempts_status = pdb_update_login_attempts(sampass, NT_STATUS_IS_OK(nt_status));

	if (!NT_STATUS_IS_OK(nt_status)) {
		bool increment_bad_pw_count = false;

		if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) &&
		    (acct_ctrl & ACB_NORMAL) &&
		    NT_STATUS_IS_OK(update_login_attempts_status))
		{
			increment_bad_pw_count =
				need_to_increment_bad_pw_count(
					challenge, sampass, user_info);
		}

		if (increment_bad_pw_count) {
			pdb_increment_bad_password_count(sampass);
			updated_badpw = True;
		} else {
			pdb_update_bad_password_count(sampass,
						      &updated_badpw);
		}
		if (updated_badpw){
			NTSTATUS status;

			become_root();
			status = pdb_update_sam_account(sampass);
			unbecome_root();

			if (!NT_STATUS_IS_OK(status)) {
				DEBUG(1, ("Failed to modify entry: %s\n",
					  nt_errstr(status)));
			}
		}
		goto done;
	}

	/*
	 * We must only reset the bad password count if the login was
	 * successful, including checking account policies
	 */
	nt_status = sam_account_ok(mem_ctx, sampass, user_info);
	if (!NT_STATUS_IS_OK(nt_status)) {
		goto done;
	}

	if ((acct_ctrl & ACB_NORMAL) &&
	    (pdb_get_bad_password_count(sampass) > 0)){
		NTSTATUS status;

		pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
		pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);

		become_root();
		status = pdb_update_sam_account(sampass);
		unbecome_root();

		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("Failed to modify entry: %s\n",
				  nt_errstr(status)));
		}
	}

	become_root();
	nt_status = make_server_info_sam(mem_ctx, sampass, server_info);
	unbecome_root();

	TALLOC_FREE(sampass);

	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status)));
		goto done;
	}

	(*server_info)->session_key =
		data_blob_talloc(*server_info, user_sess_key.data,
				 user_sess_key.length);
	data_blob_free(&user_sess_key);

	(*server_info)->lm_session_key =
		data_blob_talloc(*server_info, lm_sess_key.data,
				 lm_sess_key.length);
	data_blob_free(&lm_sess_key);

	(*server_info)->nss_token |= user_info->was_mapped;

done:
	TALLOC_FREE(sampass);
	data_blob_free(&user_sess_key);
	data_blob_free(&lm_sess_key);
	return nt_status;
}
Beispiel #16
0
/*********************************************************
 Add New User
**********************************************************/
static int new_user(const char *username, const char *fullname,
		    const char *homedir, const char *drive,
		    const char *script, const char *profile,
		    char *user_sid, bool stdin_get)
{
	char *pwd1 = NULL, *pwd2 = NULL;
	char *err = NULL, *msg = NULL;
	struct samu *sam_pwent = NULL;
	TALLOC_CTX *tosctx;
	NTSTATUS status;
	struct dom_sid u_sid;
	int flags;
	int ret;

	tosctx = talloc_tos();
	if (!tosctx) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (user_sid) {
		if (get_sid_from_cli_string(&u_sid, user_sid)) {
			fprintf(stderr, "Failed to parse SID\n");
			return -1;
		}
	}

	pwd1 = get_pass( "new password:"******"retype new password:"******"Failed to read passwords.\n");
		return -1;
	}
	ret = strcmp(pwd1, pwd2);
	if (ret != 0) {
		fprintf (stderr, "Passwords do not match!\n");
		goto done;
	}

	flags = LOCAL_ADD_USER | LOCAL_SET_PASSWORD;

	status = local_password_change(username, flags, pwd1, &err, &msg);
	if (!NT_STATUS_IS_OK(status)) {
		if (err) fprintf(stderr, "%s", err);
		ret = -1;
		goto done;
	}

	sam_pwent = samu_new(tosctx);
	if (!sam_pwent) {
		fprintf(stderr, "Out of memory!\n");
		ret = -1;
		goto done;
	}

	if (!pdb_getsampwnam(sam_pwent, username)) {
		fprintf(stderr, "User %s not found!\n", username);
		ret = -1;
		goto done;
	}

	if (fullname)
		pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
	if (homedir)
		pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
	if (drive)
		pdb_set_dir_drive(sam_pwent, drive, PDB_CHANGED);
	if (script)
		pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
	if (profile)
		pdb_set_profile_path(sam_pwent, profile, PDB_CHANGED);
	if (user_sid)
		pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);

	status = pdb_update_sam_account(sam_pwent);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr,
			"Failed to modify entry for user %s.!\n",
			username);
		ret = -1;
		goto done;
	}

	print_user_info(username, True, False);
	ret = 0;

done:
	if (pwd1) memset(pwd1, 0, strlen(pwd1));
	if (pwd2) memset(pwd2, 0, strlen(pwd2));
	SAFE_FREE(pwd1);
	SAFE_FREE(pwd2);
	SAFE_FREE(err);
	SAFE_FREE(msg);
	TALLOC_FREE(sam_pwent);
	return ret;
}
Beispiel #17
0
static int new_machine(const char *machinename, char *machine_sid)
{
	char *err = NULL, *msg = NULL;
	struct samu *sam_pwent = NULL;
	TALLOC_CTX *tosctx;
	NTSTATUS status;
	struct dom_sid m_sid;
	char *compatpwd;
	char *name;
	int flags;
	int len;
	int ret;

	len = strlen(machinename);
	if (len == 0) {
		fprintf(stderr, "No machine name given\n");
		return -1;
	}

	tosctx = talloc_tos();
	if (!tosctx) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (machine_sid) {
		if (get_sid_from_cli_string(&m_sid, machine_sid)) {
			fprintf(stderr, "Failed to parse SID\n");
			return -1;
		}
	}

	compatpwd = talloc_strdup(tosctx, machinename);
	if (!compatpwd) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (machinename[len-1] == '$') {
		name = talloc_strdup(tosctx, machinename);
		compatpwd[len-1] = '\0';
	} else {
		name = talloc_asprintf(tosctx, "%s$", machinename);
	}
	if (!name) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (!strlower_m(name)) {
		fprintf(stderr, "strlower_m %s failed\n", name);
		return -1;
	}

	flags = LOCAL_ADD_USER | LOCAL_TRUST_ACCOUNT | LOCAL_SET_PASSWORD;

	status = local_password_change(name, flags, compatpwd, &err, &msg);

	if (!NT_STATUS_IS_OK(status)) {
		if (err) fprintf(stderr, "%s", err);
		ret = -1;
	}

	sam_pwent = samu_new(tosctx);
	if (!sam_pwent) {
		fprintf(stderr, "Out of memory!\n");
		ret = -1;
		goto done;
	}

	if (!pdb_getsampwnam(sam_pwent, name)) {
		fprintf(stderr, "Machine %s not found!\n", name);
		ret = -1;
		goto done;
	}

	if (machine_sid)
		pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);

	status = pdb_update_sam_account(sam_pwent);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr,
			"Failed to modify entry for %s.!\n", name);
		ret = -1;
		goto done;
	}

	print_user_info(name, True, False);
	ret = 0;

done:
	SAFE_FREE(err);
	SAFE_FREE(msg);
	TALLOC_FREE(sam_pwent);
	return ret;
}
Beispiel #18
0
NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u)
{
	NTSTATUS status = NT_STATUS_ACCESS_DENIED;
	DOM_CRED srv_cred;
	pstring workstation;
	SAM_ACCOUNT *sampass=NULL;
	BOOL ret = False;
	unsigned char pwd[16];
	int i;
	uint32 acct_ctrl;

	/* checks and updates credentials.  creates reply credentials */
	if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->clnt_id.cred, &srv_cred)))
		return NT_STATUS_INVALID_HANDLE;

	memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));

	DEBUG(5,("_net_srv_pwset: %d\n", __LINE__));

	rpcstr_pull(workstation,q_u->clnt_id.login.uni_comp_name.buffer,
		    sizeof(workstation),q_u->clnt_id.login.uni_comp_name.uni_str_len*2,0);

	DEBUG(3,("Server Password Set by Wksta:[%s] on account [%s]\n", workstation, p->dc.mach_acct));
	
	pdb_init_sam(&sampass);

	become_root();
	ret=pdb_getsampwnam(sampass, p->dc.mach_acct);
	unbecome_root();

	/* Ensure the account exists and is a machine account. */
	
	acct_ctrl = pdb_get_acct_ctrl(sampass);

	if (!(ret 
	      && (acct_ctrl & ACB_WSTRUST ||
		      acct_ctrl & ACB_SVRTRUST ||
		      acct_ctrl & ACB_DOMTRUST))) {
		pdb_free_sam(&sampass);
		return NT_STATUS_NO_SUCH_USER;
	}
	
	if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
		pdb_free_sam(&sampass);
		return NT_STATUS_ACCOUNT_DISABLED;
	}

	DEBUG(100,("Server password set : new given value was :\n"));
	for(i = 0; i < 16; i++)
		DEBUG(100,("%02X ", q_u->pwd[i]));
	DEBUG(100,("\n"));

	cred_hash3( pwd, q_u->pwd, p->dc.sess_key, 0);

	/* lies!  nt and lm passwords are _not_ the same: don't care */
	if (!pdb_set_lanman_passwd (sampass, pwd, PDB_CHANGED)) {
		pdb_free_sam(&sampass);
		return NT_STATUS_NO_MEMORY;
	}

	if (!pdb_set_nt_passwd     (sampass, pwd, PDB_CHANGED)) {
		pdb_free_sam(&sampass);
		return NT_STATUS_NO_MEMORY;
	}

	if (!pdb_set_pass_changed_now     (sampass)) {
		pdb_free_sam(&sampass);
		/* Not quite sure what this one qualifies as, but this will do */
		return NT_STATUS_UNSUCCESSFUL; 
	}
 
	become_root();
	ret = pdb_update_sam_account (sampass);
	unbecome_root();
 
	if (ret)
		status = NT_STATUS_OK;

	/* set up the LSA Server Password Set response */
	init_net_r_srv_pwset(r_u, &srv_cred, status);

	pdb_free_sam(&sampass);
	return r_u->status;
}
Beispiel #19
0
static NTSTATUS check_sam_security(const struct auth_context *auth_context,
				   void *my_private_data, 
				   TALLOC_CTX *mem_ctx,
				   const auth_usersupplied_info *user_info, 
				   auth_serversupplied_info **server_info)
{
	struct samu *sampass=NULL;
	BOOL ret;
	NTSTATUS nt_status;
	NTSTATUS update_login_attempts_status;
	DATA_BLOB user_sess_key = data_blob(NULL, 0);
	DATA_BLOB lm_sess_key = data_blob(NULL, 0);
	BOOL updated_autolock = False, updated_badpw = False;

	if (!user_info || !auth_context) {
		return NT_STATUS_UNSUCCESSFUL;
	}

	/* Can't use the talloc version here, because the returned struct gets
	   kept on the server_info */

	if ( !(sampass = samu_new( NULL )) ) {
		return NT_STATUS_NO_MEMORY;
	}

	/* get the account information */

	become_root();
	ret = pdb_getsampwnam(sampass, user_info->internal_username);
	unbecome_root();

	if (ret == False) {
		DEBUG(3,("check_sam_security: Couldn't find user '%s' in "
			 "passdb.\n", user_info->internal_username));
		TALLOC_FREE(sampass);
		return NT_STATUS_NO_SUCH_USER;
	}

	/* see if autolock flag needs to be updated */
	if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL)
		pdb_update_autolock_flag(sampass, &updated_autolock);
	/* Quit if the account was locked out. */
	if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) {
		DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", pdb_get_username(sampass)));
		return NT_STATUS_ACCOUNT_LOCKED_OUT;
	}

	nt_status = sam_password_ok(auth_context, mem_ctx, sampass, 
				    user_info, &user_sess_key, &lm_sess_key);

	/* Notify passdb backend of login success/failure. If not NT_STATUS_OK the backend doesn't like the login */
	update_login_attempts_status = pdb_update_login_attempts(sampass, NT_STATUS_IS_OK(nt_status));
	if (!NT_STATUS_IS_OK(update_login_attempts_status))
		nt_status = update_login_attempts_status;

	if (!NT_STATUS_IS_OK(nt_status)) {
		if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) && 
		    pdb_get_acct_ctrl(sampass) &ACB_NORMAL) {  
			pdb_increment_bad_password_count(sampass);
			updated_badpw = True;
		} else {
			pdb_update_bad_password_count(sampass, 
						      &updated_badpw);
		}
		if (updated_autolock || updated_badpw){
			become_root();
			if(!NT_STATUS_IS_OK(pdb_update_sam_account(sampass)))
				DEBUG(1, ("Failed to modify entry.\n"));
			unbecome_root();
		}
		data_blob_free(&user_sess_key);
		data_blob_free(&lm_sess_key);
		TALLOC_FREE(sampass);
		return nt_status;
	}

	if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) && 
	    (pdb_get_bad_password_count(sampass) > 0)){
		pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
		pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
		updated_badpw = True;
	}

	if (updated_autolock || updated_badpw){
		become_root();
		if(!NT_STATUS_IS_OK(pdb_update_sam_account(sampass)))
			DEBUG(1, ("Failed to modify entry.\n"));
		unbecome_root();
 	}

	nt_status = sam_account_ok(mem_ctx, sampass, user_info);

	if (!NT_STATUS_IS_OK(nt_status)) {
		TALLOC_FREE(sampass);
		data_blob_free(&user_sess_key);
		data_blob_free(&lm_sess_key);
		return nt_status;
	}

	become_root();
	nt_status = make_server_info_sam(server_info, sampass);
	unbecome_root();

	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status)));
		TALLOC_FREE(sampass);
		data_blob_free(&user_sess_key);
		data_blob_free(&lm_sess_key);
		return nt_status;
	}

	(*server_info)->user_session_key =
		data_blob_talloc(*server_info, user_sess_key.data,
				 user_sess_key.length);
	data_blob_free(&user_sess_key);

	(*server_info)->lm_session_key =
		data_blob_talloc(*server_info, lm_sess_key.data,
				 lm_sess_key.length);
	data_blob_free(&lm_sess_key);

	(*server_info)->was_mapped |= user_info->was_mapped;

	return nt_status;
}
Beispiel #20
0
int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
                      int argc, const char **argv )
{
	unsigned int ctrl;
	int retval;

	const char *name;
	struct samu *sampass = NULL;
	void (*oldsig_handler)(int);

	/* Samba initialization. */
	load_case_tables();
	setup_logging( "pam_smbpass", False );
        lp_set_in_client(True);

	ctrl = set_ctrl( flags, argc, argv );

	/* get the username */

	retval = pam_get_user( pamh, &name, "Username: "******"acct: could not identify user" );
		}
		return retval;
	}
	if (on( SMB_DEBUG, ctrl )) {
		_log_err( LOG_DEBUG, "acct: username [%s] obtained", name );
	}

	if (geteuid() != 0) {
		_log_err( LOG_DEBUG, "Cannot access samba password database, not running as root.");
		return PAM_AUTHINFO_UNAVAIL;
	}

	/* Getting into places that might use LDAP -- protect the app
		from a SIGPIPE it's not expecting */
	oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
	if (!initialize_password_db(True, NULL)) {
		_log_err( LOG_ALERT, "Cannot access samba password database" );
		CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
		return PAM_AUTHINFO_UNAVAIL;
	}

	/* Get the user's record. */

	if (!(sampass = samu_new( NULL ))) {
        	CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
		/* malloc fail. */
		return nt_status_to_pam(NT_STATUS_NO_MEMORY);
	}

	if (!pdb_getsampwnam(sampass, name )) {
		_log_err( LOG_DEBUG, "acct: could not identify user" );
        	CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        	return PAM_USER_UNKNOWN;
	}

	/* check for lookup failure */
	if (!strlen(pdb_get_username(sampass)) ) {
		CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
		return PAM_USER_UNKNOWN;
	}

	if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
		if (on( SMB_DEBUG, ctrl )) {
			_log_err( LOG_DEBUG
				, "acct: account %s is administratively disabled", name );
		}
		make_remark( pamh, ctrl, PAM_ERROR_MSG
			, "Your account has been disabled; "
			"please see your system administrator." );

		CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
		return PAM_ACCT_EXPIRED;
	}

	/* TODO: support for expired passwords. */

	CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
	return PAM_SUCCESS;
}