client/smbspool.c

ソースコードを見る。

関数

static void list_devices (void)
static struct cli_statesmb_complete_connection (const char *, const char *, int, const char *, const char *, const char *, const char *, int)
static struct cli_statesmb_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 main (int argc, char *argv[])
static char * get_ticket_cache (uid_t uid)

変数

BOOL in_client


関数

static void list_devices ( void   )  [static]

smbspool.c300 行で定義されています。

参照元 main().

00301 {
00302  /*
00303   * Eventually, search the local workgroup for available hosts and printers.
00304   */
00305 
00306   puts("network smb \"Unknown\" \"Windows Printer via SAMBA\"");
00307 }

static struct cli_state * smb_complete_connection ( const char *  ,
const char *  ,
int  ,
const char *  ,
const char *  ,
const char *  ,
const char *  ,
int   
) [static]

smbspool.c373 行で定義されています。

参照先 clicli_errstr()cli_nt_error()cli_send_tconX()cli_session_setup()cli_shutdown()cli_start_connection()fprintf()get_ticket_cache()setenv()sys_getpwnam()cli_state::use_kerberos.

参照元 smb_connect().

00381 {
00382   struct cli_state  *cli;    /* New connection */    
00383   NTSTATUS nt_status;
00384   
00385   /* Start the SMB connection */
00386   nt_status = cli_start_connection( &cli, myname, server, NULL, port, 
00387                                     Undefined, flags, NULL);
00388   if (!NT_STATUS_IS_OK(nt_status)) 
00389   {
00390     return NULL;      
00391   }
00392     
00393   /* We pretty much guarentee password must be valid or a pointer
00394      to a 0 char. */
00395   if (!password) {
00396     return NULL;
00397   }
00398   
00399   if ( (username) && (*username) && 
00400       (strlen(password) == 0 ) && 
00401        (cli->use_kerberos) ) 
00402   {
00403     /* Use kerberos authentication */
00404     struct passwd *pw;
00405     char *cache_file;
00406     
00407     
00408     if ( !(pw = sys_getpwnam(username)) ) {
00409       fprintf(stderr,"ERROR Can not get %s uid\n", username);
00410       cli_shutdown(cli);
00411       return NULL;
00412     }
00413 
00414     /*
00415      * Get the ticket cache of the user to set KRB5CCNAME env
00416      * variable
00417      */
00418     cache_file = get_ticket_cache( pw->pw_uid );
00419     if ( cache_file == NULL ) 
00420     {
00421       fprintf(stderr, "ERROR: Can not get the ticket cache for %s\n", username);
00422       cli_shutdown(cli);
00423       return NULL;
00424     }
00425 
00426     if ( setenv(KRB5CCNAME, cache_file, OVERWRITE) < 0 ) 
00427     {
00428       fprintf(stderr, "ERROR: Can not add KRB5CCNAME to the environment");
00429       cli_shutdown(cli);
00430       free(cache_file);
00431       return NULL;
00432     }
00433     free(cache_file);
00434 
00435     /*
00436      * Change the UID of the process to be able to read the kerberos
00437      * ticket cache
00438      */
00439     setuid(pw->pw_uid);
00440 
00441   }
00442    
00443    
00444   if (!NT_STATUS_IS_OK(cli_session_setup(cli, username,
00445                                          password, strlen(password)+1, 
00446                                          password, strlen(password)+1,
00447                                          workgroup)))
00448   {
00449     fprintf(stderr,"ERROR: Session setup failed: %s\n", cli_errstr(cli));
00450     if (NT_STATUS_V(cli_nt_error(cli)) == 
00451         NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED))
00452     {
00453       fprintf(stderr, "did you forget to run kinit?\n");
00454     }
00455     cli_shutdown(cli);
00456 
00457     return NULL;
00458   }
00459     
00460   if (!cli_send_tconX(cli, share, "?????", password, strlen(password)+1)) 
00461   {
00462     fprintf(stderr, "ERROR: Tree connect failed (%s)\n", cli_errstr(cli));
00463     cli_shutdown(cli);
00464     return NULL;
00465   }
00466     
00467   return cli;
00468 }

static struct cli_state * smb_connect ( const char *  ,
const char *  ,
int  ,
const char *  ,
const char *  ,
const char *  ,
const char *   
) [static]

smbspool.c475 行で定義されています。

参照先 cliget_myname()mynamesmb_complete_connection().

参照元 main().

00482 {
00483   struct cli_state  *cli;    /* New connection */
00484   pstring    myname;    /* Client name */
00485   struct passwd *pwd;
00486 
00487  /*
00488   * Get the names and addresses of the client and server...
00489   */
00490 
00491   get_myname(myname);  
00492 
00493   /* See if we have a username first.  This is for backwards compatible 
00494      behavior with 3.0.14a */
00495 
00496   if ( username &&  *username )
00497   {
00498       cli = smb_complete_connection(myname, server, port, username, 
00499                                     password, workgroup, share, 0 );
00500       if (cli) 
00501         return cli;
00502   }
00503   
00504   /* 
00505    * Try to use the user kerberos credentials (if any) to authenticate
00506    */
00507   cli = smb_complete_connection(myname, server, port, jobusername, "", 
00508                                 workgroup, share, 
00509                                 CLI_FULL_CONNECTION_USE_KERBEROS );
00510 
00511   if (cli ) { return cli; }
00512 
00513   /* give a chance for a passwordless NTLMSSP session setup */
00514 
00515   pwd = getpwuid(geteuid());
00516   if (pwd == NULL) {
00517      return NULL;
00518   }
00519 
00520   cli = smb_complete_connection(myname, server, port, pwd->pw_name, "", 
00521                                 workgroup, share, 0);
00522 
00523   if (cli) { return cli; }
00524 
00525   /*
00526    * last try. Use anonymous authentication
00527    */
00528 
00529   cli = smb_complete_connection(myname, server, port, "", "", 
00530                                 workgroup, share, 0);
00531   /*
00532    * Return the new connection...
00533    */
00534   
00535   return (cli);
00536 }

static int smb_print ( struct cli_state ,
char *  ,
FILE *   
) [static]

smbspool.c544 行で定義されています。

参照先 clicli_close()cli_errstr()cli_open()cli_write()fprintf().

参照元 main().

00547 {
00548   int   fnum;           /* File number */
00549   int   nbytes,         /* Number of bytes read */
00550         tbytes;         /* Total bytes read */
00551   char  buffer[8192],   /* Buffer for copy */
00552         *ptr;           /* Pointer into tile */
00553 
00554 
00555  /*
00556   * Sanitize the title...
00557   */
00558 
00559   for (ptr = title; *ptr; ptr ++)
00560     if (!isalnum((int)*ptr) && !isspace((int)*ptr))
00561       *ptr = '_';
00562 
00563  /*
00564   * Open the printer device...
00565   */
00566 
00567   if ((fnum = cli_open(cli, title, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE)) == -1)
00568   {
00569     fprintf(stderr, "ERROR: %s opening remote spool %s\n",
00570             cli_errstr(cli), title);
00571     return (1);
00572   }
00573 
00574  /*
00575   * Copy the file to the printer...
00576   */
00577 
00578   if (fp != stdin)
00579     rewind(fp);
00580 
00581   tbytes = 0;
00582 
00583   while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
00584   {
00585     if (cli_write(cli, fnum, 0, buffer, tbytes, nbytes) != nbytes)
00586     {
00587       fprintf(stderr, "ERROR: Error writing spool: %s\n", cli_errstr(cli));
00588       break;
00589     }
00590 
00591     tbytes += nbytes;
00592   } 
00593 
00594   if (!cli_close(cli, fnum))
00595   {
00596     fprintf(stderr, "ERROR: %s closing remote spool %s\n",
00597             cli_errstr(cli), title);
00598     return (1);
00599   }
00600   else
00601     return (0);
00602 }

static char * uri_unescape_alloc ( const char *   )  [static]

smbspool.c604 行で定義されています。

参照先 rfc1738_unescape().

参照元 main().

00605 {
00606         char *ret;
00607 
00608         ret = (char *)SMB_STRDUP(uritok);
00609         if (!ret) return NULL;
00610 
00611         rfc1738_unescape(ret);
00612         return ret;
00613 }

int main ( int  argc,
char *  argv[] 
)

smbspool.c58 行で定義されています。

参照先 CatchSignal()clicli_shutdown()dyn_CONFIGFILEfpfprintf()in_clientlist_devices()load_case_tables()load_interfaces()lp_workgroup()passwordportserversetup_logging()smb_connect()smb_print()statusstrchr_m()strrchr_m()uri_unescape_alloc()usernameworkgroup.

00060 {
00061   int           i;              /* Looping var */
00062   int           copies;         /* Number of copies */
00063   int           port;           /* Port number */
00064   char          uri[1024],      /* URI */
00065                 *sep,           /* Pointer to separator */
00066                 *tmp, *tmp2,    /* Temp pointers to do escaping */
00067                 *password;      /* Password */
00068   char          *username,      /* Username */
00069                 *server,        /* Server name */
00070                 *printer;       /* Printer name */
00071   const char    *workgroup;     /* Workgroup */
00072   FILE          *fp;            /* File to print */
00073   int           status=0;               /* Status of LPD job */
00074   struct cli_state *cli;        /* SMB interface */
00075   char null_str[1];
00076   int tries = 0;
00077   const char *dev_uri;
00078 
00079   null_str[0] = '\0';
00080 
00081   /* we expect the URI in argv[0]. Detect the case where it is in argv[1] and cope */
00082   if (argc > 2 && strncmp(argv[0],"smb://", 6) && !strncmp(argv[1],"smb://", 6)) {
00083           argv++;
00084           argc--;
00085   }
00086 
00087   if (argc == 1)
00088   {
00089    /*
00090     * NEW!  In CUPS 1.1 the backends are run with no arguments to list the
00091     *       available devices.  These can be devices served by this backend
00092     *       or any other backends (i.e. you can have an SNMP backend that
00093     *       is only used to enumerate the available network printers... :)
00094     */
00095 
00096     list_devices();
00097     return (0);
00098   }
00099 
00100   if (argc < 6 || argc > 7)
00101   {
00102     fprintf(stderr, "Usage: %s [DEVICE_URI] job-id user title copies options [file]\n",
00103             argv[0]);
00104     fputs("       The DEVICE_URI environment variable can also contain the\n", stderr);
00105     fputs("       destination printer:\n", stderr);
00106     fputs("\n", stderr);
00107     fputs("           smb://[username:password@][workgroup/]server[:port]/printer\n", stderr);
00108     return (1);
00109   }
00110 
00111  /*
00112   * If we have 7 arguments, print the file named on the command-line.
00113   * Otherwise, print data from stdin...
00114   */
00115 
00116 
00117   if (argc == 6)
00118   {
00119    /*
00120     * Print from Copy stdin to a temporary file...
00121     */
00122 
00123     fp     = stdin;
00124     copies = 1;
00125   }
00126   else if ((fp = fopen(argv[6], "rb")) == NULL)
00127   {
00128     perror("ERROR: Unable to open print file");
00129     return (1);
00130   }
00131   else
00132     copies = atoi(argv[4]);
00133 
00134  /*
00135   * Find the URI...
00136   */
00137 
00138   dev_uri = getenv("DEVICE_URI");
00139   if (dev_uri)
00140     strncpy(uri, dev_uri, sizeof(uri) - 1);
00141   else if (strncmp(argv[0], "smb://", 6) == 0)
00142     strncpy(uri, argv[0], sizeof(uri) - 1);
00143   else
00144   {
00145     fputs("ERROR: No device URI found in DEVICE_URI environment variable or argv[0] !\n", stderr);
00146     return (1);
00147   }
00148 
00149   uri[sizeof(uri) - 1] = '\0';
00150 
00151  /*
00152   * Extract the destination from the URI...
00153   */
00154 
00155   if ((sep = strrchr_m(uri, '@')) != NULL)
00156   {
00157     tmp = uri + 6;
00158     *sep++ = '\0';
00159 
00160     /* username is in tmp */
00161 
00162     server = sep;
00163 
00164    /*
00165     * Extract password as needed...
00166     */
00167 
00168     if ((tmp2 = strchr_m(tmp, ':')) != NULL) {
00169       *tmp2++ = '\0';
00170       password = uri_unescape_alloc(tmp2);
00171     } else {
00172       password = null_str;
00173     }
00174     username = uri_unescape_alloc(tmp);
00175   }
00176   else
00177   {
00178     username = "dummy";
00179     password = null_str;
00180     server   = uri + 6;
00181   }
00182 
00183   tmp = server;
00184 
00185   if ((sep = strchr_m(tmp, '/')) == NULL)
00186   {
00187     fputs("ERROR: Bad URI - need printer name!\n", stderr);
00188     return (1);
00189   }
00190 
00191   *sep++ = '\0';
00192   tmp2 = sep;
00193 
00194   if ((sep = strchr_m(tmp2, '/')) != NULL)
00195   {
00196    /*
00197     * Convert to smb://[username:password@]workgroup/server/printer...
00198     */
00199 
00200     *sep++ = '\0';
00201 
00202     workgroup = uri_unescape_alloc(tmp);
00203     server    = uri_unescape_alloc(tmp2);
00204     printer   = uri_unescape_alloc(sep);
00205   }
00206   else {
00207     workgroup = NULL;
00208     server = uri_unescape_alloc(tmp);
00209     printer = uri_unescape_alloc(tmp2);
00210   }
00211   
00212   if ((sep = strrchr_m(server, ':')) != NULL)
00213   {
00214     *sep++ = '\0';
00215 
00216     port=atoi(sep);
00217   }
00218   else 
00219         port=0;
00220         
00221  
00222  /*
00223   * Setup the SAMBA server state...
00224   */
00225 
00226   setup_logging("smbspool", True);
00227 
00228   in_client = True;   /* Make sure that we tell lp_load we are */
00229 
00230   load_case_tables();
00231 
00232   if (!lp_load(dyn_CONFIGFILE, True, False, False, True))
00233   {
00234     fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
00235     return (1);
00236   }
00237 
00238   if (workgroup == NULL)
00239     workgroup = lp_workgroup();
00240 
00241   load_interfaces();
00242 
00243   do
00244   {
00245     if ((cli = smb_connect(workgroup, server, port, printer, username, password, argv[2])) == NULL)
00246     {
00247       if (getenv("CLASS") == NULL)
00248       {
00249         fprintf(stderr, "ERROR: Unable to connect to CIFS host, will retry in 60 seconds...\n");
00250         sleep (60); /* should just waiting and retrying fix authentication  ??? */
00251         tries++;
00252       }
00253       else
00254       {
00255         fprintf(stderr, "ERROR: Unable to connect to CIFS host, trying next printer...\n");
00256         return (1);
00257       }
00258     }
00259   }
00260   while ((cli == NULL) && (tries < MAX_RETRY_CONNECT));
00261 
00262   if (cli == NULL) {
00263         fprintf(stderr, "ERROR: Unable to connect to CIFS host after (tried %d times)\n", tries);
00264         return (1);
00265   }
00266 
00267  /*
00268   * Now that we are connected to the server, ignore SIGTERM so that we
00269   * can finish out any page data the driver sends (e.g. to eject the
00270   * current page...  Only ignore SIGTERM if we are printing data from
00271   * stdin (otherwise you can't cancel raw jobs...)
00272   */
00273 
00274   if (argc < 7)
00275     CatchSignal(SIGTERM, SIG_IGN);
00276 
00277  /*
00278   * Queue the job...
00279   */
00280 
00281   for (i = 0; i < copies; i ++)
00282     if ((status = smb_print(cli, argv[3] /* title */, fp)) != 0)
00283       break;
00284 
00285   cli_shutdown(cli);
00286 
00287  /*
00288   * Return the queue status...
00289   */
00290 
00291   return (status);
00292 }

static char* get_ticket_cache ( uid_t  uid  )  [static]

smbspool.c315 行で定義されています。

参照先 buffprintf()snprintf()sys_closedir()sys_opendir()sys_readdir()sys_stat()t.

参照元 smb_complete_connection().

00316 {
00317   char *ticket_file = NULL;
00318   SMB_STRUCT_DIR *tcdir;                  /* directory where ticket caches are stored */
00319   SMB_STRUCT_DIRENT *dirent;   /* directory entry */
00320   char *filename = NULL;       /* holds file names on the tmp directory */
00321   SMB_STRUCT_STAT buf;        
00322   char user_cache_prefix[CC_MAX_FILE_LEN];
00323   char file_path[CC_MAX_FILE_PATH_LEN];
00324   time_t t = 0;
00325 
00326   snprintf(user_cache_prefix, CC_MAX_FILE_LEN, "%s%d", CC_PREFIX, uid );
00327   tcdir = sys_opendir( TICKET_CC_DIR );
00328   if ( tcdir == NULL ) 
00329     return NULL; 
00330   
00331   while ( (dirent = sys_readdir( tcdir ) ) ) 
00332   { 
00333     filename = dirent->d_name;
00334     snprintf(file_path, CC_MAX_FILE_PATH_LEN,"%s/%s", TICKET_CC_DIR, filename); 
00335     if (sys_stat(file_path, &buf) == 0 ) 
00336     {
00337       if ( ( buf.st_uid == uid ) && ( S_ISREG(buf.st_mode) ) ) 
00338       {
00339         /*
00340          * check the user id of the file to prevent denial of
00341          * service attacks by creating fake ticket caches for the 
00342          * user
00343          */
00344         if ( strstr( filename, user_cache_prefix ) ) 
00345         {
00346           if ( buf.st_mtime > t ) 
00347           { 
00348             /*
00349              * a newer ticket cache found 
00350              */
00351             free(ticket_file);
00352             ticket_file=SMB_STRDUP(file_path);
00353             t = buf.st_mtime;
00354           }
00355         }
00356       }
00357     }
00358   }
00359 
00360   sys_closedir(tcdir);
00361 
00362   if ( ticket_file == NULL )
00363   {
00364     /* no ticket cache found */
00365     fprintf(stderr, "ERROR: No ticket cache found for userid=%d\n", uid);
00366     return NULL;
00367   }
00368 
00369   return ticket_file;
00370 }


変数

BOOL in_client

loadparm.c56 行で定義されています。


Sambaに対してSat Aug 29 21:23:33 2009に生成されました。  doxygen 1.4.7