関数 | |
static void | list_devices (void) |
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 | main (int argc, char *argv[]) |
static char * | get_ticket_cache (uid_t uid) |
変数 | |
BOOL | in_client |
static void list_devices | ( | void | ) | [static] |
smbspool.c の 300 行で定義されています。
参照元 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.c の 373 行で定義されています。
参照先 cli・cli_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.c の 475 行で定義されています。
参照先 cli・get_myname()・myname・smb_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.c の 544 行で定義されています。
参照先 cli・cli_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.c の 604 行で定義されています。
参照先 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.c の 58 行で定義されています。
参照先 CatchSignal()・cli・cli_shutdown()・dyn_CONFIGFILE・fp・fprintf()・in_client・list_devices()・load_case_tables()・load_interfaces()・lp_workgroup()・password・port・server・setup_logging()・smb_connect()・smb_print()・status・strchr_m()・strrchr_m()・uri_unescape_alloc()・username・workgroup.
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.c の 315 行で定義されています。
参照先 buf・fprintf()・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 }
loadparm.c の 56 行で定義されています。