1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 227b59d02dSjb150015 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23da6c28aaSamw * Use is subject to license terms. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw #pragma ident "%Z%%M% %I% %E% SMI" 27da6c28aaSamw 28da6c28aaSamw #include <sys/types.h> 29da6c28aaSamw #include <sys/varargs.h> 30da6c28aaSamw #include <string.h> 31da6c28aaSamw #include <syslog.h> 32da6c28aaSamw #include <stdlib.h> 33da6c28aaSamw 34da6c28aaSamw #include <security/pam_appl.h> 35da6c28aaSamw #include <security/pam_modules.h> 36da6c28aaSamw #include <security/pam_impl.h> 37da6c28aaSamw 38da6c28aaSamw #include <libintl.h> 39da6c28aaSamw #include <passwdutil.h> 40da6c28aaSamw 41da6c28aaSamw #include <smbsrv/libsmb.h> 42da6c28aaSamw 43da6c28aaSamw /*PRINTFLIKE3*/ 44da6c28aaSamw static void 45da6c28aaSamw error(boolean_t nowarn, pam_handle_t *pamh, char *fmt, ...) 46da6c28aaSamw { 47da6c28aaSamw va_list ap; 48da6c28aaSamw char message[PAM_MAX_MSG_SIZE]; 49da6c28aaSamw 50da6c28aaSamw if (nowarn) 51da6c28aaSamw return; 52da6c28aaSamw 53da6c28aaSamw va_start(ap, fmt); 54da6c28aaSamw (void) vsnprintf(message, sizeof (message), fmt, ap); 55da6c28aaSamw (void) __pam_display_msg(pamh, PAM_ERROR_MSG, 1, &message, 56da6c28aaSamw NULL); 57da6c28aaSamw va_end(ap); 58da6c28aaSamw } 59da6c28aaSamw 60da6c28aaSamw /*PRINTFLIKE3*/ 61da6c28aaSamw static void 62da6c28aaSamw info(boolean_t nowarn, pam_handle_t *pamh, char *fmt, ...) 63da6c28aaSamw { 64da6c28aaSamw va_list ap; 65da6c28aaSamw char message[PAM_MAX_MSG_SIZE]; 66da6c28aaSamw 67da6c28aaSamw if (nowarn) 68da6c28aaSamw return; 69da6c28aaSamw 70da6c28aaSamw va_start(ap, fmt); 71da6c28aaSamw (void) vsnprintf(message, sizeof (message), fmt, ap); 72da6c28aaSamw (void) __pam_display_msg(pamh, PAM_TEXT_INFO, 1, &message, 73da6c28aaSamw NULL); 74da6c28aaSamw va_end(ap); 75da6c28aaSamw } 76da6c28aaSamw 77da6c28aaSamw int 78da6c28aaSamw pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) 79da6c28aaSamw { 80da6c28aaSamw boolean_t debug = B_FALSE; 81da6c28aaSamw boolean_t nowarn = B_FALSE; 82da6c28aaSamw pwu_repository_t files_rep; 83da6c28aaSamw char *user, *local_user; 84da6c28aaSamw char *newpw; 85da6c28aaSamw char *service; 86da6c28aaSamw int privileged; 87da6c28aaSamw int res; 88da6c28aaSamw int i; 89da6c28aaSamw 90da6c28aaSamw for (i = 0; i < argc; i++) { 91da6c28aaSamw if (strcmp(argv[i], "debug") == 0) 92da6c28aaSamw debug = B_TRUE; 93da6c28aaSamw else if (strcmp(argv[i], "nowarn") == 0) 94da6c28aaSamw nowarn = B_TRUE; 95da6c28aaSamw } 96da6c28aaSamw 97da6c28aaSamw if ((flags & PAM_PRELIM_CHECK) != 0) 98da6c28aaSamw return (PAM_IGNORE); 99da6c28aaSamw 100da6c28aaSamw if ((flags & PAM_UPDATE_AUTHTOK) == 0) 101da6c28aaSamw return (PAM_SYSTEM_ERR); 102da6c28aaSamw 103da6c28aaSamw if ((flags & PAM_SILENT) != 0) 104da6c28aaSamw nowarn = B_TRUE; 105da6c28aaSamw 106da6c28aaSamw if (debug) 107da6c28aaSamw __pam_log(LOG_AUTH | LOG_DEBUG, 108da6c28aaSamw "pam_smb_passwd: storing authtok"); 109da6c28aaSamw 110da6c28aaSamw (void) pam_get_item(pamh, PAM_SERVICE, (void **)&service); 111da6c28aaSamw (void) pam_get_item(pamh, PAM_USER, (void **)&user); 112da6c28aaSamw 113da6c28aaSamw if (user == NULL || *user == '\0') { 114da6c28aaSamw __pam_log(LOG_AUTH | LOG_ERR, 115da6c28aaSamw "pam_smb_passwd: username is empty"); 116da6c28aaSamw return (PAM_USER_UNKNOWN); 117da6c28aaSamw } 118da6c28aaSamw 119da6c28aaSamw (void) pam_get_item(pamh, PAM_AUTHTOK, (void **)&newpw); 120da6c28aaSamw if (newpw == NULL) { 121da6c28aaSamw /* 122da6c28aaSamw * A module on the stack has removed PAM_AUTHTOK. We fail 123da6c28aaSamw */ 124da6c28aaSamw return (PAM_AUTHTOK_ERR); 125da6c28aaSamw } 126da6c28aaSamw 127da6c28aaSamw /* Check to see if this is a local user */ 128da6c28aaSamw files_rep.type = "files"; 129da6c28aaSamw files_rep.scope = NULL; 130da6c28aaSamw files_rep.scope_len = 0; 131da6c28aaSamw res = __user_to_authenticate(user, &files_rep, &local_user, 132da6c28aaSamw &privileged); 133da6c28aaSamw if (res != PWU_SUCCESS) { 134da6c28aaSamw switch (res) { 135da6c28aaSamw case PWU_NOT_FOUND: 136da6c28aaSamw /* if not a local user, ignore */ 137da6c28aaSamw if (debug) { 138da6c28aaSamw __pam_log(LOG_AUTH | LOG_DEBUG, 139da6c28aaSamw "pam_smb_passwd: %s is not local", user); 140da6c28aaSamw } 141da6c28aaSamw return (PAM_IGNORE); 142da6c28aaSamw case PWU_DENIED: 143da6c28aaSamw return (PAM_PERM_DENIED); 144da6c28aaSamw } 145da6c28aaSamw return (PAM_SYSTEM_ERR); 146da6c28aaSamw } 147da6c28aaSamw 148*3db3f65cSamw smb_pwd_init(B_FALSE); 1497b59d02dSjb150015 150da6c28aaSamw res = smb_pwd_setpasswd(user, newpw); 151da6c28aaSamw 1527b59d02dSjb150015 smb_pwd_fini(); 1537b59d02dSjb150015 154da6c28aaSamw /* 155da6c28aaSamw * now map the various return states to user messages 156da6c28aaSamw * and PAM return codes. 157da6c28aaSamw */ 158da6c28aaSamw switch (res) { 159da6c28aaSamw case SMB_PWE_SUCCESS: 160da6c28aaSamw info(nowarn, pamh, dgettext(TEXT_DOMAIN, 161da6c28aaSamw "%s: SMB password successfully changed for %s"), 162da6c28aaSamw service, user); 163da6c28aaSamw return (PAM_SUCCESS); 164da6c28aaSamw 165da6c28aaSamw case SMB_PWE_STAT_FAILED: 166da6c28aaSamw __pam_log(LOG_AUTH | LOG_ERR, 167da6c28aaSamw "%s: stat of SMB password file failed", service); 168da6c28aaSamw return (PAM_SYSTEM_ERR); 169da6c28aaSamw 170da6c28aaSamw case SMB_PWE_OPEN_FAILED: 171da6c28aaSamw case SMB_PWE_WRITE_FAILED: 172da6c28aaSamw case SMB_PWE_CLOSE_FAILED: 173da6c28aaSamw case SMB_PWE_UPDATE_FAILED: 174da6c28aaSamw error(nowarn, pamh, dgettext(TEXT_DOMAIN, 175da6c28aaSamw "%s: Unexpected failure. SMB password database unchanged."), 176da6c28aaSamw service); 177da6c28aaSamw return (PAM_SYSTEM_ERR); 178da6c28aaSamw 179da6c28aaSamw case SMB_PWE_BUSY: 180da6c28aaSamw error(nowarn, pamh, dgettext(TEXT_DOMAIN, 181da6c28aaSamw "%s: SMB password database busy. Try again later."), 182da6c28aaSamw service); 183da6c28aaSamw 184da6c28aaSamw return (PAM_AUTHTOK_LOCK_BUSY); 185da6c28aaSamw 186da6c28aaSamw case SMB_PWE_USER_UNKNOWN: 187da6c28aaSamw error(nowarn, pamh, dgettext(TEXT_DOMAIN, 188da6c28aaSamw "%s: %s does not exist."), service, user); 189da6c28aaSamw return (PAM_USER_UNKNOWN); 190da6c28aaSamw 191da6c28aaSamw case SMB_PWE_USER_DISABLE: 192da6c28aaSamw error(nowarn, pamh, dgettext(TEXT_DOMAIN, 193da6c28aaSamw "%s: %s is disable. SMB password database unchanged."), 194da6c28aaSamw service, user); 195da6c28aaSamw return (PAM_IGNORE); 196da6c28aaSamw 197da6c28aaSamw case SMB_PWE_DENIED: 198da6c28aaSamw return (PAM_PERM_DENIED); 199da6c28aaSamw 200da6c28aaSamw default: 201da6c28aaSamw res = PAM_SYSTEM_ERR; 202da6c28aaSamw break; 203da6c28aaSamw } 204da6c28aaSamw 205da6c28aaSamw return (res); 206da6c28aaSamw } 207