1 /* 2 * Copyright (c) 2001 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7 * Reserved. This file contains Original Code and/or Modifications of 8 * Original Code as defined in and that are subject to the Apple Public 9 * Source License Version 1.0 (the 'License'). You may not use this file 10 * except in compliance with the License. Please obtain a copy of the 11 * License at http://www.apple.com/publicsource and read it before using 12 * this file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 19 * License for the specific language governing rights and limitations 20 * under the License." 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24 25 #pragma ident "%Z%%M% %I% %E% SMI" 26 27 /* 28 * Routines for interacting with the user to get credentials 29 * (workgroup/domain, username, password, etc.) 30 */ 31 32 #include <stdlib.h> 33 #include <stdio.h> 34 #include <string.h> 35 #include <errno.h> 36 #include <unistd.h> 37 #include <libintl.h> 38 #include <ctype.h> 39 40 #include <netsmb/smb_lib.h> 41 #include <netsmb/smb_keychain.h> 42 43 #define MAXLINE 127 44 #define MAXPASSWD 256 /* from libc:getpass */ 45 46 static void 47 smb_tty_prompt(char *prmpt, 48 char *buf, size_t buflen) 49 { 50 char temp[MAXLINE+1]; 51 char *cp; 52 int ch; 53 54 memset(temp, 0, sizeof (temp)); 55 56 fprintf(stderr, "%s", prmpt); 57 cp = temp; 58 while ((ch = getc(stdin)) != EOF) { 59 if (ch == '\n' || ch == '\r') 60 break; 61 if (isspace(ch) || iscntrl(ch)) 62 continue; 63 *cp++ = ch; 64 if (cp == &temp[MAXLINE]) 65 break; 66 } 67 68 /* If input empty, accept default. */ 69 if (cp == temp) 70 return; 71 72 /* Use input as new value. */ 73 strncpy(buf, temp, buflen); 74 } 75 76 int 77 smb_get_authentication( 78 char *dom, size_t domlen, 79 char *usr, size_t usrlen, 80 char *passwd, size_t passwdlen, 81 const char *systemname, struct smb_ctx *ctx) 82 { 83 char *npw; 84 int error, i, kcask, kcerr; 85 86 if (ctx->ct_flags & SMBCF_KCFOUND || ctx->ct_flags & SMBCF_KCBAD) { 87 ctx->ct_flags &= ~SMBCF_KCFOUND; 88 } else { 89 ctx->ct_flags &= ~(SMBCF_KCFOUND | SMBCF_KCDOMAIN); 90 91 /* 92 * 1st: try lookup using system name 93 */ 94 kcerr = smbfs_keychain_chk(systemname, usr); 95 if (!kcerr) { 96 /* 97 * Need passwd to be not empty for existing logic. 98 * The string here is arbitrary (a debugging hint) 99 * and will be replaced in the driver by the real 100 * password from the keychain. 101 */ 102 strcpy(passwd, "$KC_SYSTEM"); 103 ctx->ct_flags |= SMBCF_KCFOUND; 104 if (smb_debug) { 105 printf("found keychain entry for" 106 " server/user: %s/%s\n", 107 systemname, usr); 108 } 109 return (0); 110 } 111 112 /* 113 * 2nd: try lookup using domain name 114 */ 115 kcerr = smbfs_keychain_chk(dom, usr); 116 if (!kcerr) { 117 /* Need passwd to be not empty... (see above) */ 118 strcpy(passwd, "$KC_DOMAIN"); 119 ctx->ct_flags |= (SMBCF_KCFOUND | SMBCF_KCDOMAIN); 120 if (smb_debug) { 121 printf("found keychain entry for" 122 " domain/user: %s/%s\n", 123 dom, usr); 124 } 125 return (0); 126 } 127 } 128 129 if (isatty(STDIN_FILENO)) { /* need command-line prompting? */ 130 if (passwd && passwd[0] == '\0') { 131 npw = getpassphrase(dgettext(TEXT_DOMAIN, "Password:")); 132 strncpy(passwd, npw, passwdlen); 133 } 134 return (0); 135 } 136 137 /* 138 * XXX: Ask the user for help, possibly via 139 * GNOME dbus or some such... (todo). 140 */ 141 smb_error(dgettext(TEXT_DOMAIN, 142 "Cannot prompt for a password when input is redirected."), 0); 143 144 return (ENOTTY); 145 } 146 147 int 148 smb_browse(struct smb_ctx *ctx, int anon) 149 { 150 /* 151 * Let user pick a share. 152 * Not supported. 153 */ 154 return (EINTR); 155 } 156