The Samba-Bugzilla – Attachment 1211 Details for
Bug 1780
smbspool can't use kerberos authentication
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch from Rodrigo Fernandez-Vizarra <Rodrigo.Fernandez-Vizarra@Sun.COM>
samba3-smbspool-krb-setuid.patch (text/plain), 8.75 KB, created by
Gerald (Jerry) Carter (dead mail address)
on 2005-05-09 08:18:41 UTC
(
hide
)
Description:
patch from Rodrigo Fernandez-Vizarra <Rodrigo.Fernandez-Vizarra@Sun.COM>
Filename:
MIME Type:
Creator:
Gerald (Jerry) Carter (dead mail address)
Created:
2005-05-09 08:18:41 UTC
Size:
8.75 KB
patch
obsolete
>Index: samba3/source/client/smbspool.c >=================================================================== >--- samba3/source/client/smbspool.c (revision 6420) >+++ samba3/source/client/smbspool.c (working copy) >@@ -4,6 +4,7 @@ > Copyright 1999 by Easy Software Products > Copyright Andrew Tridgell 1994-1998 > Copyright Andrew Bartlett 2002 >+ Copyright Rodrigo Fernandez-Vizarra 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 >@@ -20,9 +21,18 @@ > Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > */ > >+#include "includes.h" >+ >+ > #define NO_SYSLOG >+#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 strlen(TICKET_CC_DIR)+ CC_MAX_FILE_LEN+2 >+#define OVERWRITE 1 >+#define KRB5CCNAME "KRB5CCNAME" > >-#include "includes.h" > > /* > * Globals... >@@ -36,7 +46,8 @@ > */ > > static void list_devices(void); >-static struct cli_state *smb_connect(const char *, const char *, int, const char *, const char *, const char *); >+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 *); > > >@@ -97,6 +108,7 @@ > * Otherwise, print data from stdin... > */ > >+ > if (argc == 6) > { > /* >@@ -212,7 +224,7 @@ > > do > { >- if ((cli = smb_connect(workgroup, server, port, printer, username, password)) == NULL) >+ if ((cli = smb_connect(workgroup, server, port, printer, username, password, argv[2])) == NULL) > { > if (getenv("CLASS") == NULL) > { >@@ -272,40 +284,221 @@ > > > /* >- * 'smb_connect()' - Return a connection to a server. >+ * get the name of the newest ticket cache for the uid user. >+ * pam_krb5 defines a non default ticket cache for each user > */ >+static >+char * get_ticket_cache( uid_t uid ) >+{ >+ DIR *tcdir; /* directory where ticket caches are stored */ >+ SMB_STRUCT_DIRENT *dirent; /* directory entry */ >+ char *filename; /* 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; >+ time_t time; >+ >+ time = 0; >+ ticket_file = NULL; >+ filename = NULL; >+ >+ snprintf(user_cache_prefix, CC_MAX_FILE_LEN, "%s%d", CC_PREFIX, uid ); >+ tcdir = opendir( TICKET_CC_DIR ); >+ if ( tcdir == NULL ) { return NULL; } >+ >+ while ( (dirent = sys_readdir( tcdir ) ) ) >+ { >+ filename = dirent->d_name; >+ snprintf(file_path, CC_MAX_FILE_PATH_LEN,"%s/%s", TICKET_CC_DIR, filename); >+ if (sys_stat(file_path, &buf) == 0 ) >+ { >+ if ( ( buf.st_uid == uid ) && ( S_ISREG(buf.st_mode) ) ) >+ { >+ /* >+ * check the user id of the file to prevent denial of >+ * service attacks by creating fake ticket caches for the >+ * user >+ */ >+ if ( strstr( filename, user_cache_prefix ) ) >+ { >+ if ( buf.st_mtime > time ) >+ { >+ /* >+ * a newer ticket cache found >+ */ >+ free(ticket_file); >+ ticket_file=strdup(file_path); >+ time = buf.st_mtime; >+ } >+ } >+ } >+ } >+ } > >-static struct cli_state * /* O - SMB connection */ >-smb_connect(const char *workgroup, /* I - Workgroup */ >- const char *server, /* I - Server */ >- const int port, /* I - Port */ >- const char *share, /* I - Printer */ >- const char *username, /* I - Username */ >- const char *password) /* I - Password */ >+ if ( ticket_file == NULL ) >+ { >+ /* no ticket cache found */ >+ fprintf(stderr, "ERROR: No ticket cache found for userid=%d\n", uid); >+ return NULL; >+ } >+ >+ return ticket_file; >+} >+ >+static struct cli_state >+*smb_complete_connection(const char *myname, >+ const char *server, >+ int port, >+ const char *username, >+ const char *password, >+ const char *workgroup, >+ const char *share, >+ int flags) > { >- struct cli_state *c; /* New connection */ >- pstring myname; /* Client name */ >+ struct cli_state *cli; /* New connection */ > NTSTATUS nt_status; >+ >+ /* Start the SMB connection */ >+ nt_status = cli_start_connection( &cli, myname, server, NULL, port, >+ Undefined, flags, NULL); >+ if (!NT_STATUS_IS_OK(nt_status)) >+ { >+ return NULL; >+ } >+ >+ >+ if ( (username) && (*username) && >+ ((!password) || ((password) && (strlen(password) == 0 ))) && >+ (cli->use_kerberos) ) >+ { >+ /* Use kerberos authentication */ >+ struct passwd passwd; >+ struct passwd *ppasswd; >+ char buf[PW_MAX_BUF_SIZE]; >+ char *cache_file; >+ int len; >+ >+ >+ len = sysconf(_SC_GETPW_R_SIZE_MAX); >+ if (getpwnam_r(username , &passwd, buf, PW_MAX_BUF_SIZE, &ppasswd) ) >+ { >+ fprintf(stderr,"ERROR Can not get %s uid\n", username); >+ cli_shutdown(cli); >+ return NULL; >+ } > >+ /* >+ * Get the ticket cache of the user to set KRB5CCNAME env >+ * variable >+ */ >+ cache_file = get_ticket_cache( passwd.pw_uid ); >+ if ( cache_file == NULL ) >+ { >+ fprintf(stderr, "ERROR: Can not get the ticket cache for %s\n", username); >+ cli_shutdown(cli); >+ return NULL; >+ } >+ >+ if ( setenv(KRB5CCNAME, cache_file, OVERWRITE) < 0 ) >+ { >+ fprintf(stderr, "ERROR: Can not add KRB5CCNAME to the environment"); >+ cli_shutdown(cli); >+ free(cache_file); >+ return NULL; >+ } >+ free(cache_file); >+ >+ /* >+ * Change the UID of the process to be able to read the kerberos >+ * ticket cache >+ */ >+ setuid(passwd.pw_uid); >+ >+ } >+ >+ >+ if (!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)) == >+ NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)) >+ { >+ fprintf(stderr, "did you forget to run kinit?\n"); >+ } >+ cli_shutdown(cli); >+ >+ return NULL; >+ } >+ >+ if (!cli_send_tconX(cli, share, "?????",password, strlen(password)+1)) >+ { >+ cli_shutdown(cli); >+ fprintf(stderr, "ERROR: Tree connect failed\n" ); >+ return NULL; >+ } >+ >+ return cli; >+} >+ >+/* >+ * 'smb_connect()' - Return a connection to a server. >+ */ >+ >+static struct cli_state * /* O - SMB connection */ >+smb_connect(const char *workgroup, /* I - Workgroup */ >+ const char *server, /* I - Server */ >+ const int port, /* I - Port */ >+ const char *share, /* I - Printer */ >+ const char *username, /* I - Username */ >+ const char *password, /* I - Password */ >+ const char *jobusername) /* I - User who issued the print job */ >+{ >+ struct cli_state *cli; /* New connection */ >+ pstring myname; /* Client name */ >+ struct nmb_name called, calling; >+ uid_t olduid; >+ int flags; >+ > /* > * Get the names and addresses of the client and server... > */ > > get_myname(myname); >- >- nt_status = cli_full_connection(&c, myname, server, NULL, port, share, "?????", >- username, workgroup, password, 0, Undefined, NULL); >+ >+ if ( (username) && ( *username ) && (password) && (*password) ) >+ { >+ /* >+ * User/password specified in the DEVICE_URI, use those credentials >+ * to connect to the server >+ */ >+ cli = smb_complete_connection(myname, server, port, username, >+ password, workgroup, share, 0 ); >+ if (cli ) { return cli; } >+ } > >- if (!NT_STATUS_IS_OK(nt_status)) { >- fprintf(stderr, "ERROR: Connection failed with error %s\n", nt_errstr(nt_status)); >- return NULL; >- } >+ /* >+ * Try to use the user kerberos credentials (if any) to authenticate >+ */ >+ cli = smb_complete_connection(myname, server, port, jobusername, "", >+ workgroup, share, >+ CLI_FULL_CONNECTION_USE_KERBEROS ); > >+ if (cli ) { return cli; } >+ > /* >+ * last try. Use anonymous authentication >+ */ >+ cli = smb_complete_connection(myname, server, port, "", "", >+ workgroup, share, 0); >+ >+ /* > * Return the new connection... > */ > >- return (c); >+ return (cli); > } > >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 1780
: 1211