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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#define PW_MAX_BUF_SIZE sysconf(_SC_GETPW_R_SIZE_MAX)
#define TICKET_CC_DIR "/tmp"
#define CC_PREFIX "krb5cc_" /* prefix of the ticket cache */
#define CC_MAX_FILE_LEN 24
#define CC_MAX_FILE_PATH_LEN (sizeof(TICKET_CC_DIR)-1)+ CC_MAX_FILE_LEN+2
#define OVERWRITE 1
#define KRB5CCNAME "KRB5CCNAME"
+#define MAX_RETRY_CONNECT 3
/*
* Globals...
*/
-extern BOOL in_client; /* Boolean for client library */
+extern bool in_client; /* Boolean for client library */
/*
static struct cli_state *smb_complete_connection(const char *, const char *,int , const char *, const char *, const char *, const char *, int);
static struct cli_state *smb_connect(const char *, const char *, int, const char *, const char *, const char *, const char *);
static int smb_print(struct cli_state *, char *, FILE *);
+static char * uri_unescape_alloc(const char *);
/*
int port; /* Port number */
char uri[1024], /* URI */
*sep, /* Pointer to separator */
+ *tmp, *tmp2, /* Temp pointers to do escaping */
*password; /* Password */
- const char *username, /* Username */
+ char *username, /* Username */
*server, /* Server name */
*printer; /* Printer name */
const char *workgroup; /* Workgroup */
FILE *fp; /* File to print */
int status=0; /* Status of LPD job */
struct cli_state *cli; /* SMB interface */
+ char null_str[1];
+ int tries = 0;
+ const char *dev_uri;
+
+ null_str[0] = '\0';
/* we expect the URI in argv[0]. Detect the case where it is in argv[1] and cope */
if (argc > 2 && strncmp(argv[0],"smb://", 6) && !strncmp(argv[1],"smb://", 6)) {
* Find the URI...
*/
- if (getenv("DEVICE_URI") != NULL)
- strncpy(uri, getenv("DEVICE_URI"), sizeof(uri) - 1);
+ dev_uri = getenv("DEVICE_URI");
+ if (dev_uri)
+ strncpy(uri, dev_uri, sizeof(uri) - 1);
else if (strncmp(argv[0], "smb://", 6) == 0)
strncpy(uri, argv[0], sizeof(uri) - 1);
else
if ((sep = strrchr_m(uri, '@')) != NULL)
{
- username = uri + 6;
+ tmp = uri + 6;
*sep++ = '\0';
+ /* username is in tmp */
+
server = sep;
/*
* Extract password as needed...
*/
- if ((password = strchr_m(username, ':')) != NULL)
- *password++ = '\0';
- else
- password = "";
+ if ((tmp2 = strchr_m(tmp, ':')) != NULL) {
+ *tmp2++ = '\0';
+ password = uri_unescape_alloc(tmp2);
+ } else {
+ password = null_str;
+ }
+ username = uri_unescape_alloc(tmp);
}
else
{
- username = "";
- password = "";
+ username = null_str;
+ password = null_str;
server = uri + 6;
}
- if ((sep = strchr_m(server, '/')) == NULL)
+ tmp = server;
+
+ if ((sep = strchr_m(tmp, '/')) == NULL)
{
fputs("ERROR: Bad URI - need printer name!\n", stderr);
return (1);
}
*sep++ = '\0';
- printer = sep;
+ tmp2 = sep;
- if ((sep = strchr_m(printer, '/')) != NULL)
+ if ((sep = strchr_m(tmp2, '/')) != NULL)
{
/*
* Convert to smb://[username:password@]workgroup/server/printer...
*sep++ = '\0';
- workgroup = server;
- server = printer;
- printer = sep;
+ workgroup = uri_unescape_alloc(tmp);
+ server = uri_unescape_alloc(tmp2);
+ printer = uri_unescape_alloc(sep);
}
- else
+ else {
workgroup = NULL;
+ server = uri_unescape_alloc(tmp);
+ printer = uri_unescape_alloc(tmp2);
+ }
if ((sep = strrchr_m(server, ':')) != NULL)
{
port=atoi(sep);
}
- else
+ else
port=0;
in_client = True; /* Make sure that we tell lp_load we are */
- if (!lp_load(dyn_CONFIGFILE, True, False, False))
+ load_case_tables();
+
+ if (!lp_load(dyn_CONFIGFILE, True, False, False, True))
{
fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
return (1);
{
if (getenv("CLASS") == NULL)
{
- fprintf(stderr, "ERROR: Unable to connect to CIFS host, will retry in 60 seconds...");
+ fprintf(stderr, "ERROR: Unable to connect to CIFS host, will retry in 60 seconds...\n");
sleep (60); /* should just waiting and retrying fix authentication ??? */
+ tries++;
}
else
{
- fprintf(stderr, "ERROR: Unable to connect to CIFS host, trying next printer...");
+ fprintf(stderr, "ERROR: Unable to connect to CIFS host, trying next printer...\n");
return (1);
}
}
}
- while (cli == NULL);
+ while ((cli == NULL) && (tries < MAX_RETRY_CONNECT));
+
+ if (cli == NULL) {
+ fprintf(stderr, "ERROR: Unable to connect to CIFS host after (tried %d times)\n", tries);
+ return (1);
+ }
/*
* Now that we are connected to the server, ignore SIGTERM so that we
static
char * get_ticket_cache( uid_t uid )
{
+ char *ticket_file = NULL;
SMB_STRUCT_DIR *tcdir; /* directory where ticket caches are stored */
SMB_STRUCT_DIRENT *dirent; /* directory entry */
char *filename = NULL; /* holds file names on the tmp directory */
SMB_STRUCT_STAT buf;
char user_cache_prefix[CC_MAX_FILE_LEN];
char file_path[CC_MAX_FILE_PATH_LEN];
- char *ticket_file = NULL;
time_t t = 0;
-
+
snprintf(user_cache_prefix, CC_MAX_FILE_LEN, "%s%d", CC_PREFIX, uid );
tcdir = sys_opendir( TICKET_CC_DIR );
if ( tcdir == NULL )
if ( ticket_file == NULL )
{
-#ifdef DEVELOPER
/* no ticket cache found */
fprintf(stderr, "ERROR: No ticket cache found for userid=%d\n", uid);
-#endif
return NULL;
}
return NULL;
}
-
+ /* We pretty much guarentee password must be valid or a pointer
+ to a 0 char. */
+ if (!password) {
+ return NULL;
+ }
+
if ( (username) && (*username) &&
- ((!password) || ((password) && (strlen(password) == 0 ))) &&
+ (strlen(password) == 0 ) &&
(cli->use_kerberos) )
{
/* Use kerberos authentication */
}
- if (!cli_session_setup(cli, username, password, strlen(password)+1,
- password, strlen(password)+1,
- workgroup))
+ if (!NT_STATUS_IS_OK(cli_session_setup(cli, username,
+ password, strlen(password)+1,
+ password, strlen(password)+1,
+ workgroup)))
{
fprintf(stderr,"ERROR: Session setup failed: %s\n", cli_errstr(cli));
if (NT_STATUS_V(cli_nt_error(cli)) ==
{
struct cli_state *cli; /* New connection */
pstring myname; /* Client name */
+ struct passwd *pwd;
/*
* Get the names and addresses of the client and server...
if (cli ) { return cli; }
+ /* give a chance for a passwordless NTLMSSP session setup */
+
+ pwd = getpwuid(geteuid());
+ if (pwd == NULL) {
+ return NULL;
+ }
+
+ cli = smb_complete_connection(myname, server, port, pwd->pw_name, "",
+ workgroup, share, 0);
+
+ if (cli) { return cli; }
+
/*
* last try. Use anonymous authentication
*/
+
cli = smb_complete_connection(myname, server, port, "", "",
workgroup, share, 0);
-
/*
* Return the new connection...
*/
else
return (0);
}
+
+static char *uri_unescape_alloc(const char *uritok)
+{
+ char *ret;
+
+ ret = (char *)SMB_STRDUP(uritok);
+ if (!ret) return NULL;
+
+ rfc1738_unescape(ret);
+ return ret;
+}