1*4bff34e3Sthurlow /* 2*4bff34e3Sthurlow * CDDL HEADER START 3*4bff34e3Sthurlow * 4*4bff34e3Sthurlow * The contents of this file are subject to the terms of the 5*4bff34e3Sthurlow * Common Development and Distribution License (the "License"). 6*4bff34e3Sthurlow * You may not use this file except in compliance with the License. 7*4bff34e3Sthurlow * 8*4bff34e3Sthurlow * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*4bff34e3Sthurlow * or http://www.opensolaris.org/os/licensing. 10*4bff34e3Sthurlow * See the License for the specific language governing permissions 11*4bff34e3Sthurlow * and limitations under the License. 12*4bff34e3Sthurlow * 13*4bff34e3Sthurlow * When distributing Covered Code, include this CDDL HEADER in each 14*4bff34e3Sthurlow * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*4bff34e3Sthurlow * If applicable, add the following below this CDDL HEADER, with the 16*4bff34e3Sthurlow * fields enclosed by brackets "[]" replaced with your own identifying 17*4bff34e3Sthurlow * information: Portions Copyright [yyyy] [name of copyright owner] 18*4bff34e3Sthurlow * 19*4bff34e3Sthurlow * CDDL HEADER END 20*4bff34e3Sthurlow */ 21*4bff34e3Sthurlow /* 22*4bff34e3Sthurlow * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*4bff34e3Sthurlow * Use is subject to license terms. 24*4bff34e3Sthurlow */ 25*4bff34e3Sthurlow 26*4bff34e3Sthurlow #pragma ident "%Z%%M% %I% %E% SMI" 27*4bff34e3Sthurlow 28*4bff34e3Sthurlow #include <sys/types.h> 29*4bff34e3Sthurlow #include <sys/varargs.h> 30*4bff34e3Sthurlow #include <string.h> 31*4bff34e3Sthurlow #include <syslog.h> 32*4bff34e3Sthurlow #include <stdlib.h> 33*4bff34e3Sthurlow #include <unistd.h> 34*4bff34e3Sthurlow #include <pwd.h> 35*4bff34e3Sthurlow #include <nss_dbdefs.h> 36*4bff34e3Sthurlow 37*4bff34e3Sthurlow #include <security/pam_appl.h> 38*4bff34e3Sthurlow #include <security/pam_modules.h> 39*4bff34e3Sthurlow #include <security/pam_impl.h> 40*4bff34e3Sthurlow 41*4bff34e3Sthurlow #include <libintl.h> 42*4bff34e3Sthurlow #include <passwdutil.h> 43*4bff34e3Sthurlow 44*4bff34e3Sthurlow #include <errno.h> 45*4bff34e3Sthurlow #include <netsmb/smb_keychain.h> 46*4bff34e3Sthurlow 47*4bff34e3Sthurlow /*ARGSUSED*/ 48*4bff34e3Sthurlow int 49*4bff34e3Sthurlow pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) 50*4bff34e3Sthurlow { 51*4bff34e3Sthurlow return (PAM_IGNORE); 52*4bff34e3Sthurlow } 53*4bff34e3Sthurlow 54*4bff34e3Sthurlow /*ARGSUSED*/ 55*4bff34e3Sthurlow int 56*4bff34e3Sthurlow pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) 57*4bff34e3Sthurlow { 58*4bff34e3Sthurlow boolean_t debug = B_FALSE; 59*4bff34e3Sthurlow char dom[20]; 60*4bff34e3Sthurlow char *user; 61*4bff34e3Sthurlow char *pw; 62*4bff34e3Sthurlow char *service; 63*4bff34e3Sthurlow struct passwd pwbuf; 64*4bff34e3Sthurlow char buf[NSS_BUFLEN_PASSWD]; 65*4bff34e3Sthurlow char *home; 66*4bff34e3Sthurlow uid_t uid; 67*4bff34e3Sthurlow int res = PAM_SUCCESS; 68*4bff34e3Sthurlow int i, mask; 69*4bff34e3Sthurlow 70*4bff34e3Sthurlow for (i = 0; i < argc; i++) { 71*4bff34e3Sthurlow if (strcmp(argv[i], "debug") == 0) 72*4bff34e3Sthurlow debug = B_TRUE; 73*4bff34e3Sthurlow } 74*4bff34e3Sthurlow 75*4bff34e3Sthurlow /* Since our creds don't time out, ignore a refresh. */ 76*4bff34e3Sthurlow if ((flags & PAM_REFRESH_CRED) != 0) 77*4bff34e3Sthurlow return (PAM_IGNORE); 78*4bff34e3Sthurlow 79*4bff34e3Sthurlow /* Check for unknown options */ 80*4bff34e3Sthurlow mask = PAM_ESTABLISH_CRED | PAM_REINITIALIZE_CRED | PAM_DELETE_CRED; 81*4bff34e3Sthurlow if ((flags & ~mask) != 0) 82*4bff34e3Sthurlow return (PAM_IGNORE); 83*4bff34e3Sthurlow 84*4bff34e3Sthurlow (void) pam_get_item(pamh, PAM_SERVICE, (void **)&service); 85*4bff34e3Sthurlow (void) pam_get_item(pamh, PAM_USER, (void **)&user); 86*4bff34e3Sthurlow 87*4bff34e3Sthurlow if (user == NULL || *user == '\0') { 88*4bff34e3Sthurlow __pam_log(LOG_AUTH | LOG_ERR, 89*4bff34e3Sthurlow "pam_smbfs_login: username is empty"); 90*4bff34e3Sthurlow return (PAM_IGNORE); 91*4bff34e3Sthurlow } 92*4bff34e3Sthurlow if (getpwnam_r(user, &pwbuf, buf, sizeof (buf)) == NULL) { 93*4bff34e3Sthurlow __pam_log(LOG_AUTH | LOG_ERR, 94*4bff34e3Sthurlow "pam_smbfs_login: username %s can't be found", user); 95*4bff34e3Sthurlow return (PAM_IGNORE); 96*4bff34e3Sthurlow } 97*4bff34e3Sthurlow uid = pwbuf.pw_uid; 98*4bff34e3Sthurlow home = pwbuf.pw_dir; 99*4bff34e3Sthurlow 100*4bff34e3Sthurlow (void) pam_get_item(pamh, PAM_AUTHTOK, (void **)&pw); 101*4bff34e3Sthurlow if (pw == NULL) { 102*4bff34e3Sthurlow /* 103*4bff34e3Sthurlow * A module on the stack has removed PAM_AUTHTOK. 104*4bff34e3Sthurlow */ 105*4bff34e3Sthurlow return (PAM_IGNORE); 106*4bff34e3Sthurlow } 107*4bff34e3Sthurlow 108*4bff34e3Sthurlow res = smbfs_default_dom_usr(home, NULL, dom, sizeof (dom), NULL, 0); 109*4bff34e3Sthurlow if (res != 0) 110*4bff34e3Sthurlow (void) strcpy(dom, "WORKGROUP"); 111*4bff34e3Sthurlow 112*4bff34e3Sthurlow if (debug) 113*4bff34e3Sthurlow __pam_log(LOG_AUTH | LOG_DEBUG, 114*4bff34e3Sthurlow "pam_smbfs_login: service %s, dom %s, user %s", 115*4bff34e3Sthurlow service, dom, user); 116*4bff34e3Sthurlow 117*4bff34e3Sthurlow if ((flags & (PAM_ESTABLISH_CRED | PAM_REINITIALIZE_CRED)) != 0) 118*4bff34e3Sthurlow res = smbfs_keychain_add(uid, dom, user, pw); 119*4bff34e3Sthurlow 120*4bff34e3Sthurlow if ((flags & PAM_DELETE_CRED) != 0) 121*4bff34e3Sthurlow res = smbfs_keychain_del(uid, dom, user); 122*4bff34e3Sthurlow 123*4bff34e3Sthurlow /* 124*4bff34e3Sthurlow * map errors to user messages and PAM return codes. 125*4bff34e3Sthurlow */ 126*4bff34e3Sthurlow switch (res) { 127*4bff34e3Sthurlow case SMB_KEYCHAIN_SUCCESS: 128*4bff34e3Sthurlow if (debug) 129*4bff34e3Sthurlow __pam_log(LOG_AUTH | LOG_DEBUG, 130*4bff34e3Sthurlow "smbfs password successfully stored for %s", user); 131*4bff34e3Sthurlow break; 132*4bff34e3Sthurlow 133*4bff34e3Sthurlow case SMB_KEYCHAIN_BADPASSWD: 134*4bff34e3Sthurlow __pam_log(LOG_AUTH | LOG_ERR, "smbfs password is invalid"); 135*4bff34e3Sthurlow break; 136*4bff34e3Sthurlow 137*4bff34e3Sthurlow case SMB_KEYCHAIN_BADDOMAIN: 138*4bff34e3Sthurlow __pam_log(LOG_AUTH | LOG_ERR, 139*4bff34e3Sthurlow "%s: smbfs domain %s is invalid", service, dom); 140*4bff34e3Sthurlow break; 141*4bff34e3Sthurlow 142*4bff34e3Sthurlow case SMB_KEYCHAIN_BADUSER: 143*4bff34e3Sthurlow __pam_log(LOG_AUTH | LOG_ERR, "smbfs user %s is invalid", user); 144*4bff34e3Sthurlow break; 145*4bff34e3Sthurlow 146*4bff34e3Sthurlow case SMB_KEYCHAIN_NODRIVER: 147*4bff34e3Sthurlow __pam_log(LOG_AUTH | LOG_ERR, 148*4bff34e3Sthurlow "driver open failed (%s), smbfs password not stored", 149*4bff34e3Sthurlow strerror(errno)); 150*4bff34e3Sthurlow break; 151*4bff34e3Sthurlow 152*4bff34e3Sthurlow case SMB_KEYCHAIN_UNKNOWN: 153*4bff34e3Sthurlow __pam_log(LOG_AUTH | LOG_ERR, 154*4bff34e3Sthurlow "Unexpected failure, smbfs password not stored"); 155*4bff34e3Sthurlow break; 156*4bff34e3Sthurlow 157*4bff34e3Sthurlow default: 158*4bff34e3Sthurlow __pam_log(LOG_AUTH | LOG_ERR, 159*4bff34e3Sthurlow "driver ioctl failed (%s), smbfs password not stored", 160*4bff34e3Sthurlow strerror(errno)); 161*4bff34e3Sthurlow break; 162*4bff34e3Sthurlow } 163*4bff34e3Sthurlow 164*4bff34e3Sthurlow return (PAM_IGNORE); 165*4bff34e3Sthurlow } 166