17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5c5d759b6Sjjj  * Common Development and Distribution License (the "License").
6c5d759b6Sjjj  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22dd1104fbSMichen Chang  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <string.h>
277c478bd9Sstevel@tonic-gate #include <syslog.h>
287c478bd9Sstevel@tonic-gate #include "passwdutil.h"
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate int
__incr_failed_count(char * username,char * repname,int max_failures)317c478bd9Sstevel@tonic-gate __incr_failed_count(char *username, char *repname, int max_failures)
327c478bd9Sstevel@tonic-gate {
337c478bd9Sstevel@tonic-gate 	int ret;
347c478bd9Sstevel@tonic-gate 	void *buf;
357c478bd9Sstevel@tonic-gate 	attrlist items[1];
36dd1104fbSMichen Chang 	int repnum = name_to_int(repname);
37dd1104fbSMichen Chang 	repops_t *ops;
387c478bd9Sstevel@tonic-gate 
39dd1104fbSMichen Chang 	/* account locking only defined for files and ldap */
40dd1104fbSMichen Chang 	if ((repnum != REP_FILES) &&
41dd1104fbSMichen Chang 	    (repnum != REP_LDAP)) {
427c478bd9Sstevel@tonic-gate 		return (PWU_SUCCESS);
43dd1104fbSMichen Chang 	}
447c478bd9Sstevel@tonic-gate 
45dd1104fbSMichen Chang 	ops = rops[repnum];
46dd1104fbSMichen Chang 	if ((ops->lock != NULL) &&
47dd1104fbSMichen Chang 	    (ret = ops->lock()) != PWU_SUCCESS) {
487c478bd9Sstevel@tonic-gate 		return (ret);
49dd1104fbSMichen Chang 	}
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate 	items[0].type = ATTR_INCR_FAILED_LOGINS;
527c478bd9Sstevel@tonic-gate 	items[0].next = NULL;
53dd1104fbSMichen Chang 	if ((ret = ops->getpwnam(username, items, NULL, &buf)) != PWU_SUCCESS) {
547c478bd9Sstevel@tonic-gate 		goto out;
55dd1104fbSMichen Chang 	}
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate 	/* We increment the failed count by one */
58dd1104fbSMichen Chang 	if ((ret = ops->update(items, NULL, buf)) != PWU_SUCCESS) {
597c478bd9Sstevel@tonic-gate 		goto out;
60dd1104fbSMichen Chang 	}
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	/* Did we just exceed "max_failures" ? */
63c5d759b6Sjjj 	if (items[0].data.val_i >= max_failures) {
647c478bd9Sstevel@tonic-gate 		syslog(LOG_AUTH|LOG_NOTICE,
657c478bd9Sstevel@tonic-gate 		    "Excessive (%d) login failures for %s: locking account.",
667c478bd9Sstevel@tonic-gate 		    max_failures, username);
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 		items[0].type = ATTR_LOCK_ACCOUNT;
697c478bd9Sstevel@tonic-gate 		if ((ret = ops->update(items, NULL, buf)) != PWU_SUCCESS)
707c478bd9Sstevel@tonic-gate 			goto out;
717c478bd9Sstevel@tonic-gate 	}
72*36e852a1SRaja Andra 	if (((ret = ops->putpwnam(username, NULL, NULL, buf)) ==
7347d0cd5cSgww 	    PWU_SUCCESS) &&
7447d0cd5cSgww 	    (items[0].type == ATTR_LOCK_ACCOUNT))
7547d0cd5cSgww 		ret = PWU_ACCOUNT_LOCKED;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate out:
78dd1104fbSMichen Chang 	if (ops->unlock != NULL) {
79dd1104fbSMichen Chang 		ops->unlock();
80dd1104fbSMichen Chang 	}
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	return (ret);
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate /*
867c478bd9Sstevel@tonic-gate  * reset the failed count.
877c478bd9Sstevel@tonic-gate  * returns the number of failed logins before the reset, or an error (< 0)
887c478bd9Sstevel@tonic-gate  */
897c478bd9Sstevel@tonic-gate int
__rst_failed_count(char * username,char * repname)907c478bd9Sstevel@tonic-gate __rst_failed_count(char *username, char *repname)
917c478bd9Sstevel@tonic-gate {
927c478bd9Sstevel@tonic-gate 	int ret;
937c478bd9Sstevel@tonic-gate 	void *buf;
947c478bd9Sstevel@tonic-gate 	attrlist items[1];
95dd1104fbSMichen Chang 	int repnum = name_to_int(repname);
96dd1104fbSMichen Chang 	repops_t *ops;
977c478bd9Sstevel@tonic-gate 
98dd1104fbSMichen Chang 	/* account locking only defined for files and ldap */
99dd1104fbSMichen Chang 	if ((repnum != REP_FILES) &&
100dd1104fbSMichen Chang 	    (repnum != REP_LDAP)) {
1017c478bd9Sstevel@tonic-gate 		return (PWU_SUCCESS);
102dd1104fbSMichen Chang 	}
1037c478bd9Sstevel@tonic-gate 
104dd1104fbSMichen Chang 	ops = rops[repnum];
105dd1104fbSMichen Chang 	if ((ops->lock != NULL) &&
106dd1104fbSMichen Chang 	    (ret = ops->lock()) != PWU_SUCCESS) {
1077c478bd9Sstevel@tonic-gate 		return (ret);
108dd1104fbSMichen Chang 	}
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	items[0].type = ATTR_RST_FAILED_LOGINS;
1117c478bd9Sstevel@tonic-gate 	items[0].next = NULL;
1127c478bd9Sstevel@tonic-gate 	if ((ret = ops->getpwnam(username, items, NULL, &buf)) != PWU_SUCCESS)
1137c478bd9Sstevel@tonic-gate 		goto out;
1147c478bd9Sstevel@tonic-gate 	if ((ret = ops->update(items, NULL, buf)) != PWU_SUCCESS)
1157c478bd9Sstevel@tonic-gate 		goto out;
116*36e852a1SRaja Andra 	ret = ops->putpwnam(username, NULL, NULL, buf);
1177c478bd9Sstevel@tonic-gate out:
118dd1104fbSMichen Chang 	if (ops->unlock != NULL) {
119dd1104fbSMichen Chang 		ops->unlock();
120dd1104fbSMichen Chang 	}
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 	return (ret != PWU_SUCCESS ? ret : items[0].data.val_i);
1237c478bd9Sstevel@tonic-gate }
124