xref: /titanic_44/usr/src/lib/libsmbfs/smb/ui-sun.c (revision bfed486ad8de8b8ebc6345a8e10accae08bf2f45)
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