00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 extern pstring user_socket_options;
00038 extern BOOL AllowDebugChange;
00039 extern BOOL override_logfile;
00040
00041 struct user_auth_info cmdline_auth_info;
00042
00043 static void set_logfile(poptContext con, const char * arg)
00044 {
00045
00046 pstring logfile;
00047 const char *pname;
00048
00049
00050 pname = strrchr_m(poptGetInvocationName(con),'/');
00051
00052 if (!pname)
00053 pname = poptGetInvocationName(con);
00054 else
00055 pname++;
00056
00057 pstr_sprintf(logfile, "%s/%s.log", arg, pname);
00058 lp_set_logfile(logfile);
00059 }
00060
00061 static void popt_common_callback(poptContext con,
00062 enum poptCallbackReason reason,
00063 const struct poptOption *opt,
00064 const char *arg, const void *data)
00065 {
00066
00067 if (reason == POPT_CALLBACK_REASON_PRE) {
00068 set_logfile(con, dyn_LOGFILEBASE);
00069 return;
00070 }
00071
00072 switch(opt->val) {
00073 case 'd':
00074 if (arg) {
00075 debug_parse_levels(arg);
00076 AllowDebugChange = False;
00077 }
00078 break;
00079
00080 case 'V':
00081 printf( "Version %s\n", SAMBA_VERSION_STRING);
00082 exit(0);
00083 break;
00084
00085 case 'O':
00086 if (arg) {
00087 pstrcpy(user_socket_options,arg);
00088 }
00089 break;
00090
00091 case 's':
00092 if (arg) {
00093 pstrcpy(dyn_CONFIGFILE, arg);
00094 }
00095 break;
00096
00097 case 'n':
00098 if (arg) {
00099 set_global_myname_override(arg);
00100 }
00101 break;
00102
00103 case 'l':
00104 if (arg) {
00105 set_logfile(con, arg);
00106 override_logfile = True;
00107 pstr_sprintf(dyn_LOGFILEBASE, "%s", arg);
00108 }
00109 break;
00110
00111 case 'i':
00112 if (arg) {
00113 set_global_scope(arg);
00114 }
00115 break;
00116
00117 case 'W':
00118 if (arg) {
00119 set_global_myworkgroup(arg);
00120 }
00121 break;
00122 }
00123 }
00124
00125 struct poptOption popt_common_connection[] = {
00126 { NULL, 0, POPT_ARG_CALLBACK, (void *)popt_common_callback },
00127 { "socket-options", 'O', POPT_ARG_STRING, NULL, 'O', "socket options to use",
00128 "SOCKETOPTIONS" },
00129 { "netbiosname", 'n', POPT_ARG_STRING, NULL, 'n', "Primary netbios name", "NETBIOSNAME" },
00130 { "workgroup", 'W', POPT_ARG_STRING, NULL, 'W', "Set the workgroup name", "WORKGROUP" },
00131 { "scope", 'i', POPT_ARG_STRING, NULL, 'i', "Use this Netbios scope", "SCOPE" },
00132
00133 POPT_TABLEEND
00134 };
00135
00136 struct poptOption popt_common_samba[] = {
00137 { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE, (void *)popt_common_callback },
00138 { "debuglevel", 'd', POPT_ARG_STRING, NULL, 'd', "Set debug level", "DEBUGLEVEL" },
00139 { "configfile", 's', POPT_ARG_STRING, NULL, 's', "Use alternate configuration file", "CONFIGFILE" },
00140 { "log-basename", 'l', POPT_ARG_STRING, NULL, 'l', "Base name for log files", "LOGFILEBASE" },
00141 { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version" },
00142 POPT_TABLEEND
00143 };
00144
00145 struct poptOption popt_common_version[] = {
00146 { NULL, 0, POPT_ARG_CALLBACK, (void *)popt_common_callback },
00147 { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version" },
00148 POPT_TABLEEND
00149 };
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 enum dyn_item{
00166 DYN_SBINDIR = 1,
00167 DYN_BINDIR,
00168 DYN_SWATDIR,
00169 DYN_LMHOSTSFILE,
00170 DYN_LIBDIR,
00171 DYN_SHLIBEXT,
00172 DYN_LOCKDIR,
00173 DYN_PIDDIR,
00174 DYN_SMB_PASSWD_FILE,
00175 DYN_PRIVATE_DIR,
00176 };
00177
00178
00179 static void popt_dynconfig_callback(poptContext con,
00180 enum poptCallbackReason reason,
00181 const struct poptOption *opt,
00182 const char *arg, const void *data)
00183 {
00184
00185 switch (opt->val) {
00186 case DYN_SBINDIR:
00187 if (arg) {
00188 dyn_SBINDIR = SMB_STRDUP(arg);
00189 }
00190 break;
00191
00192 case DYN_BINDIR:
00193 if (arg) {
00194 dyn_BINDIR = SMB_STRDUP(arg);
00195 }
00196 break;
00197
00198 case DYN_SWATDIR:
00199 if (arg) {
00200 dyn_SWATDIR = SMB_STRDUP(arg);
00201 }
00202 break;
00203
00204 case DYN_LMHOSTSFILE:
00205 if (arg) {
00206 pstrcpy(dyn_LMHOSTSFILE, arg);
00207 }
00208 break;
00209
00210 case DYN_LIBDIR:
00211 if (arg) {
00212 pstrcpy(dyn_LIBDIR, arg);
00213 }
00214 break;
00215
00216 case DYN_SHLIBEXT:
00217 if (arg) {
00218 fstrcpy(dyn_SHLIBEXT, arg);
00219 }
00220 break;
00221
00222 case DYN_LOCKDIR:
00223 if (arg) {
00224 pstrcpy(dyn_LOCKDIR, arg);
00225 }
00226 break;
00227
00228 case DYN_PIDDIR:
00229 if (arg) {
00230 pstrcpy(dyn_PIDDIR, arg);
00231 }
00232 break;
00233
00234 case DYN_SMB_PASSWD_FILE:
00235 if (arg) {
00236 pstrcpy(dyn_SMB_PASSWD_FILE, arg);
00237 }
00238 break;
00239
00240 case DYN_PRIVATE_DIR:
00241 if (arg) {
00242 pstrcpy(dyn_PRIVATE_DIR, arg);
00243 }
00244 break;
00245
00246 }
00247 }
00248
00249 const struct poptOption popt_common_dynconfig[] = {
00250
00251 { NULL, '\0', POPT_ARG_CALLBACK, (void *)popt_dynconfig_callback },
00252
00253 { "sbindir", '\0' , POPT_ARG_STRING, NULL, DYN_SBINDIR,
00254 "Path to sbin directory", "SBINDIR" },
00255 { "bindir", '\0' , POPT_ARG_STRING, NULL, DYN_BINDIR,
00256 "Path to bin directory", "BINDIR" },
00257 { "swatdir", '\0' , POPT_ARG_STRING, NULL, DYN_SWATDIR,
00258 "Path to SWAT installation directory", "SWATDIR" },
00259 { "lmhostsfile", '\0' , POPT_ARG_STRING, NULL, DYN_LMHOSTSFILE,
00260 "Path to lmhosts file", "LMHOSTSFILE" },
00261 { "libdir", '\0' , POPT_ARG_STRING, NULL, DYN_LIBDIR,
00262 "Path to shared library directory", "LIBDIR" },
00263 { "shlibext", '\0' , POPT_ARG_STRING, NULL, DYN_SHLIBEXT,
00264 "Shared library extension", "SHLIBEXT" },
00265 { "lockdir", '\0' , POPT_ARG_STRING, NULL, DYN_LOCKDIR,
00266 "Path to lock file directory", "LOCKDIR" },
00267 { "piddir", '\0' , POPT_ARG_STRING, NULL, DYN_PIDDIR,
00268 "Path to PID file directory", "PIDDIR" },
00269 { "smb-passwd-file", '\0' , POPT_ARG_STRING, NULL, DYN_SMB_PASSWD_FILE,
00270 "Path to smbpasswd file", "SMB_PASSWD_FILE" },
00271 { "private-dir", '\0' , POPT_ARG_STRING, NULL, DYN_PRIVATE_DIR,
00272 "Path to private data directory", "PRIVATE_DIR" },
00273
00274 POPT_TABLEEND
00275 };
00276
00277
00278
00279
00280
00281 static void get_password_file(struct user_auth_info *a)
00282 {
00283 int fd = -1;
00284 char *p;
00285 BOOL close_it = False;
00286 pstring spec;
00287 char pass[128];
00288
00289 if ((p = getenv("PASSWD_FD")) != NULL) {
00290 pstrcpy(spec, "descriptor ");
00291 pstrcat(spec, p);
00292 sscanf(p, "%d", &fd);
00293 close_it = False;
00294 } else if ((p = getenv("PASSWD_FILE")) != NULL) {
00295 fd = sys_open(p, O_RDONLY, 0);
00296 pstrcpy(spec, p);
00297 if (fd < 0) {
00298 fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
00299 spec, strerror(errno));
00300 exit(1);
00301 }
00302 close_it = True;
00303 }
00304
00305 for(p = pass, *p = '\0';
00306 p && p - pass < sizeof(pass);) {
00307 switch (read(fd, p, 1)) {
00308 case 1:
00309 if (*p != '\n' && *p != '\0') {
00310 *++p = '\0';
00311 break;
00312 }
00313 case 0:
00314 if (p - pass) {
00315 *p = '\0';
00316 p = NULL;
00317 break;
00318 } else {
00319 fprintf(stderr, "Error reading password from file %s: %s\n",
00320 spec, "empty password\n");
00321 exit(1);
00322 }
00323
00324 default:
00325 fprintf(stderr, "Error reading password from file %s: %s\n",
00326 spec, strerror(errno));
00327 exit(1);
00328 }
00329 }
00330 pstrcpy(a->password, pass);
00331 if (close_it)
00332 close(fd);
00333 }
00334
00335 static void get_credentials_file(const char *file, struct user_auth_info *info)
00336 {
00337 XFILE *auth;
00338 fstring buf;
00339 uint16 len = 0;
00340 char *ptr, *val, *param;
00341
00342 if ((auth=x_fopen(file, O_RDONLY, 0)) == NULL)
00343 {
00344
00345 d_printf("ERROR: Unable to open credentials file!\n");
00346 exit(-1);
00347 }
00348
00349 while (!x_feof(auth))
00350 {
00351
00352 if (!x_fgets(buf, sizeof(buf), auth))
00353 continue;
00354 len = strlen(buf);
00355
00356 if ((len) && (buf[len-1]=='\n'))
00357 {
00358 buf[len-1] = '\0';
00359 len--;
00360 }
00361 if (len == 0)
00362 continue;
00363
00364
00365
00366 param = buf;
00367 if (!(ptr = strchr_m (buf, '=')))
00368 continue;
00369
00370 val = ptr+1;
00371 *ptr = '\0';
00372
00373
00374 while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
00375 val++;
00376
00377 if (strwicmp("password", param) == 0)
00378 {
00379 pstrcpy(info->password, val);
00380 info->got_pass = True;
00381 }
00382 else if (strwicmp("username", param) == 0)
00383 pstrcpy(info->username, val);
00384 else if (strwicmp("domain", param) == 0)
00385 set_global_myworkgroup(val);
00386 memset(buf, 0, sizeof(buf));
00387 }
00388 x_fclose(auth);
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 static void popt_common_credentials_callback(poptContext con,
00402 enum poptCallbackReason reason,
00403 const struct poptOption *opt,
00404 const char *arg, const void *data)
00405 {
00406 char *p;
00407
00408 if (reason == POPT_CALLBACK_REASON_PRE) {
00409 cmdline_auth_info.use_kerberos = False;
00410 cmdline_auth_info.got_pass = False;
00411 cmdline_auth_info.signing_state = Undefined;
00412 pstrcpy(cmdline_auth_info.username, "GUEST");
00413
00414 if (getenv("LOGNAME"))pstrcpy(cmdline_auth_info.username,getenv("LOGNAME"));
00415
00416 if (getenv("USER")) {
00417 pstrcpy(cmdline_auth_info.username,getenv("USER"));
00418
00419 if ((p = strchr_m(cmdline_auth_info.username,'%'))) {
00420 *p = 0;
00421 pstrcpy(cmdline_auth_info.password,p+1);
00422 cmdline_auth_info.got_pass = True;
00423 memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(cmdline_auth_info.password));
00424 }
00425 }
00426
00427 if (getenv("PASSWD")) {
00428 pstrcpy(cmdline_auth_info.password,getenv("PASSWD"));
00429 cmdline_auth_info.got_pass = True;
00430 }
00431
00432 if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
00433 get_password_file(&cmdline_auth_info);
00434 cmdline_auth_info.got_pass = True;
00435 }
00436
00437 return;
00438 }
00439
00440 switch(opt->val) {
00441 case 'U':
00442 {
00443 char *lp;
00444
00445 pstrcpy(cmdline_auth_info.username,arg);
00446 if ((lp=strchr_m(cmdline_auth_info.username,'%'))) {
00447 *lp = 0;
00448 pstrcpy(cmdline_auth_info.password,lp+1);
00449 cmdline_auth_info.got_pass = True;
00450 memset(strchr_m(arg,'%')+1,'X',strlen(cmdline_auth_info.password));
00451 }
00452 }
00453 break;
00454
00455 case 'A':
00456 get_credentials_file(arg, &cmdline_auth_info);
00457 break;
00458
00459 case 'k':
00460 #ifndef HAVE_KRB5
00461 d_printf("No kerberos support compiled in\n");
00462 exit(1);
00463 #else
00464 cmdline_auth_info.use_kerberos = True;
00465 cmdline_auth_info.got_pass = True;
00466 #endif
00467 break;
00468
00469 case 'S':
00470 {
00471 cmdline_auth_info.signing_state = -1;
00472 if (strequal(arg, "off") || strequal(arg, "no") || strequal(arg, "false"))
00473 cmdline_auth_info.signing_state = False;
00474 else if (strequal(arg, "on") || strequal(arg, "yes") || strequal(arg, "true") ||
00475 strequal(arg, "auto") )
00476 cmdline_auth_info.signing_state = True;
00477 else if (strequal(arg, "force") || strequal(arg, "required") || strequal(arg, "forced"))
00478 cmdline_auth_info.signing_state = Required;
00479 else {
00480 fprintf(stderr, "Unknown signing option %s\n", arg );
00481 exit(1);
00482 }
00483 }
00484 break;
00485 case 'P':
00486 {
00487 char *opt_password = NULL;
00488
00489
00490
00491 if (!secrets_init()) {
00492 d_printf("ERROR: Unable to open secrets database\n");
00493 exit(1);
00494 }
00495
00496 opt_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
00497
00498 if (!opt_password) {
00499 d_printf("ERROR: Unable to fetch machine password\n");
00500 exit(1);
00501 }
00502 pstr_sprintf(cmdline_auth_info.username, "%s$",
00503 global_myname());
00504 pstrcpy(cmdline_auth_info.password,opt_password);
00505 SAFE_FREE(opt_password);
00506
00507
00508 cmdline_auth_info.use_kerberos = True;
00509 cmdline_auth_info.got_pass = True;
00510 }
00511 break;
00512 }
00513 }
00514
00515
00516
00517 struct poptOption popt_common_credentials[] = {
00518 { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE, (void *)popt_common_credentials_callback },
00519 { "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "USERNAME" },
00520 { "no-pass", 'N', POPT_ARG_NONE, &cmdline_auth_info.got_pass, 0, "Don't ask for a password" },
00521 { "kerberos", 'k', POPT_ARG_NONE, &cmdline_auth_info.use_kerberos, 'k', "Use kerberos (active directory) authentication" },
00522 { "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" },
00523 { "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" },
00524 {"machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password" },
00525 POPT_TABLEEND
00526 };