summaryrefslogtreecommitdiff
path: root/source4/lib/cmdline
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2005-03-21 02:08:38 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:11:08 -0500
commit02075be0bbc2095073f8898350fded64a7c97c79 (patch)
tree28ea2820f79dfc766b745515848c840bf98b2a88 /source4/lib/cmdline
parent105660d3f9b537fa47fe6e33c0418a1d8f85e0e9 (diff)
downloadsamba-02075be0bbc2095073f8898350fded64a7c97c79.tar.gz
samba-02075be0bbc2095073f8898350fded64a7c97c79.tar.bz2
samba-02075be0bbc2095073f8898350fded64a7c97c79.zip
r5917: First step in using the new cli_credentials structure. This patch
puts support for it into popt_common, adds a few utility functions (in lib/credentials.c) and the callback functions for the command-line (lib/cmdline/credentials.c). Comments are welcome :-) (This used to be commit 1d49b57c50fe8c2683ea23e9df41ce8ad774db98)
Diffstat (limited to 'source4/lib/cmdline')
-rw-r--r--source4/lib/cmdline/config.m419
-rw-r--r--source4/lib/cmdline/config.mk7
-rw-r--r--source4/lib/cmdline/credentials.c49
-rw-r--r--source4/lib/cmdline/getsmbpass.c158
-rw-r--r--source4/lib/cmdline/popt_common.c303
-rw-r--r--source4/lib/cmdline/popt_common.h9
6 files changed, 269 insertions, 276 deletions
diff --git a/source4/lib/cmdline/config.m4 b/source4/lib/cmdline/config.m4
index e2121d1f14..45c3a70f9f 100644
--- a/source4/lib/cmdline/config.m4
+++ b/source4/lib/cmdline/config.m4
@@ -77,4 +77,21 @@ SMB_EXT_LIB(READLINE, [${TMP_LIBCMDLINE_LIBS}])
SMB_SUBSYSTEM(LIBCMDLINE,[],
[${TMP_LIBCMDLINE_OBJS}],
[],
- [LIBPOPT EXT_LIB_READLINE EXT_LIB_ALLLIBS])
+ [LIBPOPT EXT_LIB_READLINE EXT_LIB_ALLLIBS LIBCMDLINE_CREDENTIALS])
+
+AC_CACHE_CHECK([whether getpass should be replaced],samba_cv_REPLACE_GETPASS,[
+SAVE_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper"
+AC_TRY_COMPILE([
+#define REPLACE_GETPASS 1
+#define NO_CONFIG_H 1
+#define main dont_declare_main
+#include "${srcdir-.}/lib/cmdline/getsmbpass.c"
+#undef main
+],[],samba_cv_REPLACE_GETPASS=yes,samba_cv_REPLACE_GETPASS=no)
+CPPFLAGS="$SAVE_CPPFLAGS"
+])
+if test x"$samba_cv_REPLACE_GETPASS" = x"yes"; then
+ AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced])
+fi
+
diff --git a/source4/lib/cmdline/config.mk b/source4/lib/cmdline/config.mk
new file mode 100644
index 0000000000..803c81f273
--- /dev/null
+++ b/source4/lib/cmdline/config.mk
@@ -0,0 +1,7 @@
+##############################
+# Start SUBSYSTEM LIBCMDLINE_CREDENTIALS
+[SUBSYSTEM::LIBCMDLINE_CREDENTIALS]
+ADD_OBJ_FILES = lib/cmdline/getsmbpass.o \
+ lib/cmdline/credentials.o
+# End SUBSYSTEM LIBCMDLINE_CREDENTIALS
+##############################
diff --git a/source4/lib/cmdline/credentials.c b/source4/lib/cmdline/credentials.c
new file mode 100644
index 0000000000..d827baed76
--- /dev/null
+++ b/source4/lib/cmdline/credentials.c
@@ -0,0 +1,49 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Jelmer Vernooij 2005
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "version.h"
+#include "dynconfig.h"
+#include "system/filesys.h"
+#include "system/passwd.h"
+#include "lib/cmdline/popt_common.h"
+
+static const char *cmdline_get_userpassword(struct cli_credentials *credentials)
+{
+ char *prompt;
+ char *ret;
+
+ prompt = talloc_asprintf(NULL, "Password for [%s\\%s]:",
+ cli_credentials_get_domain(credentials),
+ cli_credentials_get_username(credentials));
+
+ ret = getpass(prompt);
+
+ talloc_free(prompt);
+ return ret;
+}
+
+void cli_credentials_set_cmdline_callbacks(struct cli_credentials *cred)
+{
+ if (cred->password_obtained <= CRED_CALLBACK) {
+ cred->password_cb = cmdline_get_userpassword;
+ cred->password_obtained = CRED_CALLBACK;
+ }
+}
diff --git a/source4/lib/cmdline/getsmbpass.c b/source4/lib/cmdline/getsmbpass.c
new file mode 100644
index 0000000000..4ffcde8dfd
--- /dev/null
+++ b/source4/lib/cmdline/getsmbpass.c
@@ -0,0 +1,158 @@
+/* Copyright (C) 1992-1998 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+/* Modified to use with samba by Jeremy Allison, 8th July 1995. */
+
+#include "includes.h"
+#include "system/terminal.h"
+#include "system/wait.h"
+
+#ifdef REPLACE_GETPASS
+
+#ifdef SYSV_TERMIO
+
+/* SYSTEM V TERMIO HANDLING */
+
+static struct termio t;
+
+#define ECHO_IS_ON(t) ((t).c_lflag & ECHO)
+#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO)
+#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO)
+
+#ifndef TCSAFLUSH
+#define TCSAFLUSH 1
+#endif
+
+#ifndef TCSANOW
+#define TCSANOW 0
+#endif
+
+static int tcgetattr(int fd, struct termio *_t)
+{
+ return ioctl(fd, TCGETA, _t);
+}
+
+static int tcsetattr(int fd, int flags, struct termio *_t)
+{
+ if(flags & TCSAFLUSH)
+ ioctl(fd, TCFLSH, TCIOFLUSH);
+ return ioctl(fd, TCSETS, _t);
+}
+
+#elif !defined(TCSAFLUSH)
+
+/* BSD TERMIO HANDLING */
+
+static struct sgttyb t;
+
+#define ECHO_IS_ON(t) ((t).sg_flags & ECHO)
+#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO)
+#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO)
+
+#define TCSAFLUSH 1
+#define TCSANOW 0
+
+static int tcgetattr(int fd, struct sgttyb *_t)
+{
+ return ioctl(fd, TIOCGETP, (char *)_t);
+}
+
+static int tcsetattr(int fd, int flags, struct sgttyb *_t)
+{
+ return ioctl(fd, TIOCSETP, (char *)_t);
+}
+
+#else /* POSIX TERMIO HANDLING */
+#define ECHO_IS_ON(t) ((t).c_lflag & ECHO)
+#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO)
+#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO)
+
+static struct termios t;
+#endif /* SYSV_TERMIO */
+
+char *getsmbpass(const char *prompt)
+{
+ FILE *in, *out;
+ int echo_off;
+ static char buf[256];
+ static size_t bufsize = sizeof(buf);
+ size_t nread;
+
+ /* Catch problematic signals */
+ CatchSignal(SIGINT, SIGNAL_CAST SIG_IGN);
+
+ /* Try to write to and read from the terminal if we can.
+ If we can't open the terminal, use stderr and stdin. */
+
+ in = fopen ("/dev/tty", "w+");
+ if (in == NULL)
+ {
+ in = stdin;
+ out = stderr;
+ }
+ else
+ out = in;
+
+ setvbuf(in, NULL, _IONBF, 0);
+
+ /* Turn echoing off if it is on now. */
+
+ if (tcgetattr (fileno (in), &t) == 0)
+ {
+ if (ECHO_IS_ON(t))
+ {
+ TURN_ECHO_OFF(t);
+ echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0;
+ TURN_ECHO_ON(t);
+ }
+ else
+ echo_off = 0;
+ }
+ else
+ echo_off = 0;
+
+ /* Write the prompt. */
+ fputs (prompt, out);
+ fflush (out);
+
+ /* Read the password. */
+ buf[0] = 0;
+ fgets(buf, bufsize, in);
+ nread = strlen(buf);
+ if (buf[nread - 1] == '\n')
+ buf[nread - 1] = '\0';
+
+ /* Restore echoing. */
+ if (echo_off)
+ (void) tcsetattr (fileno (in), TCSANOW, &t);
+
+ if (in != stdin)
+ /* We opened the terminal; now close it. */
+ fclose (in);
+
+ /* Catch problematic signals */
+ CatchSignal(SIGINT, SIGNAL_CAST SIG_DFL);
+
+ printf("\n");
+ return buf;
+}
+
+#else
+ void getsmbpasswd_dummy(void);
+ void getsmbpasswd_dummy(void) {;}
+#endif
diff --git a/source4/lib/cmdline/popt_common.c b/source4/lib/cmdline/popt_common.c
index 0445877e7a..0792a16b3d 100644
--- a/source4/lib/cmdline/popt_common.c
+++ b/source4/lib/cmdline/popt_common.c
@@ -38,10 +38,9 @@
* -i,--scope
*/
-
enum {OPT_OPTION=1,OPT_LEAK_REPORT,OPT_LEAK_REPORT_FULL};
-static struct cmdline_auth_info cmdline_auth_info;
+struct cli_credentials *cmdline_credentials = NULL;
static void popt_common_callback(poptContext con,
enum poptCallbackReason reason,
@@ -160,182 +159,34 @@ struct poptOption popt_common_version[] = {
POPT_TABLEEND
};
-
-
-/****************************************************************************
- * get a password from a a file or file descriptor
- * exit on failure
- * ****************************************************************************/
-static void get_password_file(struct cmdline_auth_info *a)
-{
- int fd = -1;
- char *p;
- BOOL close_it = False;
- pstring spec;
- char pass[128];
-
- if ((p = getenv("PASSWD_FD")) != NULL) {
- pstrcpy(spec, "descriptor ");
- pstrcat(spec, p);
- sscanf(p, "%d", &fd);
- close_it = False;
- } else if ((p = getenv("PASSWD_FILE")) != NULL) {
- fd = open(p, O_RDONLY, 0);
- pstrcpy(spec, p);
- if (fd < 0) {
- fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
- spec, strerror(errno));
- exit(1);
- }
- close_it = True;
- }
-
- for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
- p && p - pass < sizeof(pass);) {
- switch (read(fd, p, 1)) {
- case 1:
- if (*p != '\n' && *p != '\0') {
- *++p = '\0'; /* advance p, and null-terminate pass */
- break;
- }
- case 0:
- if (p - pass) {
- *p = '\0'; /* null-terminate it, just in case... */
- p = NULL; /* then force the loop condition to become false */
- break;
- } else {
- fprintf(stderr, "Error reading password from file %s: %s\n",
- spec, "empty password\n");
- exit(1);
- }
-
- default:
- fprintf(stderr, "Error reading password from file %s: %s\n",
- spec, strerror(errno));
- exit(1);
- }
- }
- pstrcpy(a->password, pass);
- if (close_it)
- close(fd);
-}
-
-static void get_credentials_file(const char *file, struct cmdline_auth_info *info)
-{
- XFILE *auth;
- fstring buf;
- uint16_t len = 0;
- char *ptr, *val, *param;
-
- if ((auth=x_fopen(file, O_RDONLY, 0)) == NULL)
- {
- /* fail if we can't open the credentials file */
- d_printf("ERROR: Unable to open credentials file!\n");
- exit(-1);
- }
-
- while (!x_feof(auth))
- {
- /* get a line from the file */
- if (!x_fgets(buf, sizeof(buf), auth))
- continue;
- len = strlen(buf);
-
- if ((len) && (buf[len-1]=='\n'))
- {
- buf[len-1] = '\0';
- len--;
- }
- if (len == 0)
- continue;
-
- /* break up the line into parameter & value.
- * will need to eat a little whitespace possibly */
- param = buf;
- if (!(ptr = strchr_m (buf, '=')))
- continue;
-
- val = ptr+1;
- *ptr = '\0';
-
- /* eat leading white space */
- while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
- val++;
-
- if (strwicmp("password", param) == 0) {
- pstrcpy(info->password, val);
- info->got_pass = True;
- } else if (strwicmp("username", param) == 0) {
- pstrcpy(info->username, val);
- } else if (strwicmp("domain", param) == 0) {
- pstrcpy(info->domain,val);
- info->got_domain = True;
- }
- memset(buf, 0, sizeof(buf));
- }
- x_fclose(auth);
-}
-
/* Handle command line options:
* -U,--user
* -A,--authentication-file
* -k,--use-kerberos
* -N,--no-pass
* -S,--signing
- * -P --machine-pass
+ * -P --machine-pass
*/
+static BOOL dont_ask = False;
+
static void popt_common_credentials_callback(poptContext con,
enum poptCallbackReason reason,
const struct poptOption *opt,
const char *arg, const void *data)
{
- char *p;
-
if (reason == POPT_CALLBACK_REASON_PRE) {
- cmdline_auth_info.use_kerberos = False;
- cmdline_auth_info.got_pass = False;
- pstrcpy(cmdline_auth_info.username, "GUEST");
-
- if (getenv("LOGNAME"))pstrcpy(cmdline_auth_info.username,getenv("LOGNAME"));
-
- if (getenv("USER")) {
- pstring tmp;
-
- pstrcpy(cmdline_auth_info.username,getenv("USER"));
+ cmdline_credentials = talloc_zero(talloc_autofree_context(), struct cli_credentials);
+ cli_credentials_guess(cmdline_credentials);
- pstrcpy(tmp,cmdline_auth_info.username);
- if ((p = strchr_m(tmp,'\\'))) {
- *p = 0;
- pstrcpy(cmdline_auth_info.domain,tmp);
- cmdline_auth_info.got_domain = True;
- pstrcpy(cmdline_auth_info.username,p+1);
- }
-
- if ((p = strchr_m(cmdline_auth_info.username,'%'))) {
- *p = 0;
- pstrcpy(cmdline_auth_info.password,p+1);
- cmdline_auth_info.got_pass = True;
- memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(cmdline_auth_info.password));
- }
- }
-
- if (getenv("DOMAIN")) {
- pstrcpy(cmdline_auth_info.domain,getenv("DOMAIN"));
- cmdline_auth_info.got_domain = True;
- }
-
- if (getenv("PASSWD")) {
- pstrcpy(cmdline_auth_info.password,getenv("PASSWD"));
- cmdline_auth_info.got_pass = True;
- }
-
- if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
- get_password_file(&cmdline_auth_info);
- cmdline_auth_info.got_pass = True;
+ return;
+ }
+
+ if (reason == POPT_CALLBACK_REASON_POST) {
+ if (!dont_ask) {
+ cli_credentials_set_cmdline_callbacks(cmdline_credentials);
}
-
return;
}
@@ -343,41 +194,18 @@ static void popt_common_credentials_callback(poptContext con,
case 'U':
{
char *lp;
- pstring tmp;
-
- pstrcpy(cmdline_auth_info.username,arg);
- pstrcpy(tmp,cmdline_auth_info.username);
- if ((p = strchr_m(tmp,'\\'))) {
- *p = 0;
- pstrcpy(cmdline_auth_info.domain,tmp);
- cmdline_auth_info.got_domain = True;
- pstrcpy(cmdline_auth_info.username,p+1);
- }
+ cli_credentials_parse_string(cmdline_credentials,arg, CRED_SPECIFIED);
- if ((lp=strchr_m(cmdline_auth_info.username,'%'))) {
+ if ((lp=strchr_m(arg,'%'))) {
*lp = 0;
- pstrcpy(cmdline_auth_info.password,lp+1);
- cmdline_auth_info.got_pass = True;
- memset(strchr_m(arg,'%')+1,'X',strlen(cmdline_auth_info.password));
+ memset(strchr_m(arg,'%')+1,'X',strlen(cmdline_credentials->password));
}
}
break;
case 'A':
- get_credentials_file(arg, &cmdline_auth_info);
- break;
-
- case 'k':
-#ifndef HAVE_KRB5
- d_printf("No kerberos support compiled in\n");
- exit(1);
-#else
- cmdline_auth_info.use_kerberos = True;
- cmdline_auth_info.got_pass = True;
- lp_set_cmdline("gensec:krb5", "True");
- lp_set_cmdline("gensec:ms_krb5", "True");
-#endif
+ cli_credentials_parse_file(cmdline_credentials, arg, CRED_SPECIFIED);
break;
case 'S':
@@ -401,97 +229,38 @@ static void popt_common_credentials_callback(poptContext con,
d_printf("ERROR: Unable to fetch machine password\n");
exit(1);
}
- snprintf(cmdline_auth_info.username, sizeof(cmdline_auth_info.username),
- "%s$", lp_netbios_name());
- pstrcpy(cmdline_auth_info.password,opt_password);
+ cmdline_credentials->username = talloc_asprintf(cmdline_credentials, "%s$", lp_netbios_name());
+ cmdline_credentials->username_obtained = CRED_SPECIFIED;
+ cli_credentials_set_password(cmdline_credentials, opt_password, CRED_SPECIFIED);
free(opt_password);
- cmdline_auth_info.got_pass = True;
- pstrcpy(cmdline_auth_info.domain, lp_workgroup());
- cmdline_auth_info.got_domain = True;
-
- /* machine accounts only work with kerberos */
- cmdline_auth_info.use_kerberos = True;
+ cli_credentials_set_domain(cmdline_credentials, lp_workgroup(), CRED_SPECIFIED);
}
+ /* machine accounts only work with kerberos */
+
+ case 'k':
+#ifndef HAVE_KRB5
+ d_printf("No kerberos support compiled in\n");
+ exit(1);
+#else
+ lp_set_cmdline("gensec:krb5", "True");
+ lp_set_cmdline("gensec:ms_krb5", "True");
+#endif
break;
+
+
}
}
struct poptOption popt_common_credentials[] = {
- { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE, popt_common_credentials_callback },
+ { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST, popt_common_credentials_callback },
{ "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "USERNAME" },
- { "no-pass", 'N', POPT_ARG_NONE, &cmdline_auth_info.got_pass, 0, "Don't ask for a password" },
- { "kerberos", 'k', POPT_ARG_NONE, &cmdline_auth_info.use_kerberos, 'k', "Use kerberos (active directory) authentication" },
+ { "no-pass", 'N', POPT_ARG_NONE, &dont_ask, True, "Don't ask for a password" },
+ { "kerberos", 'k', POPT_ARG_NONE, NULL, 'k', "Use kerberos (active directory) authentication" },
{ "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" },
{ "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" },
- { "machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password" },
+ { "machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password (implies -k)" },
POPT_TABLEEND
};
-
-void cmdline_set_username(const char *name)
-{
- pstrcpy(cmdline_auth_info.username, name);
-}
-
-const char *cmdline_get_username(void)
-{
- return cmdline_auth_info.username;
-}
-
-void cmdline_set_userdomain(const char *domain)
-{
- cmdline_auth_info.got_domain = True;
- pstrcpy(cmdline_auth_info.domain, domain);
-}
-
-const char *cmdline_get_userdomain(void)
-{
- if (cmdline_auth_info.got_domain) {
- return cmdline_auth_info.domain;
- }
-
- /* I think this should be lp_netbios_name()
- * instead of lp_workgroup(), because if you're logged in
- * as domain user the getenv("USER") contains the domain
- * and this code path isn't used
- * --metze
- */
- return lp_netbios_name();
-}
-
-const char *cmdline_get_userpassword(void)
-{
- char *prompt;
- char *ret;
-
- if (cmdline_auth_info.got_pass) {
- return cmdline_auth_info.password;
- }
-
- prompt = talloc_asprintf(NULL, "Password for [%s\\%s]:",
- cmdline_get_userdomain(),
- cmdline_get_username());
-
- ret = getpass(prompt);
-
- talloc_free(prompt);
- return ret;
-}
-
-void cmdline_set_userpassword(const char *pass)
-{
- cmdline_auth_info.got_pass = True;
- pstrcpy(cmdline_auth_info.password, pass);
-}
-
-void cmdline_set_use_kerberos(BOOL use_kerberos)
-{
- cmdline_auth_info.use_kerberos = use_kerberos;
-}
-
-BOOL cmdline_get_use_kerberos(void)
-{
- return cmdline_auth_info.use_kerberos;
-}
diff --git a/source4/lib/cmdline/popt_common.h b/source4/lib/cmdline/popt_common.h
index d6ae43d083..28676de56b 100644
--- a/source4/lib/cmdline/popt_common.h
+++ b/source4/lib/cmdline/popt_common.h
@@ -39,13 +39,6 @@ extern struct poptOption popt_common_credentials[];
#define POPT_COMMON_VERSION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version, 0, "Common samba options:", NULL },
#define POPT_COMMON_CREDENTIALS { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_credentials, 0, "Authentication options:", NULL },
-struct cmdline_auth_info {
- pstring username;
- pstring domain;
- BOOL got_domain;
- pstring password;
- BOOL got_pass;
- BOOL use_kerberos;
-};
+extern struct cli_credentials *cmdline_credentials;
#endif /* _POPT_COMMON_H */