int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { unsigned int ctrl; int retval, *ret_data = NULL; struct samu *sampass = NULL; const char *name; void (*oldsig_handler)(int) = NULL; bool found; /* Points to memory managed by the PAM library. Do not free. */ char *p = NULL; /* Samba initialization. */ load_case_tables(); lp_set_in_client(True); ctrl = set_ctrl(pamh, flags, argc, argv); /* Get a few bytes so we can pass our return value to pam_sm_setcred(). */ ret_data = SMB_MALLOC_P(int); /* we need to do this before we call AUTH_RETURN */ /* Getting into places that might use LDAP -- protect the app from a SIGPIPE it's not expecting */ oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN); /* get the username */ retval = pam_get_user( pamh, &name, "Username: "******"auth: could not identify user"); } AUTH_RETURN; } if (on( SMB_DEBUG, ctrl )) { _log_err(pamh, LOG_DEBUG, "username [%s] obtained", name ); } if (geteuid() != 0) { _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root."); retval = PAM_AUTHINFO_UNAVAIL; AUTH_RETURN; } if (!initialize_password_db(True, NULL)) { _log_err(pamh, LOG_ALERT, "Cannot access samba password database" ); retval = PAM_AUTHINFO_UNAVAIL; AUTH_RETURN; } sampass = samu_new( NULL ); if (!sampass) { _log_err(pamh, LOG_ALERT, "Cannot talloc a samu struct" ); retval = nt_status_to_pam(NT_STATUS_NO_MEMORY); AUTH_RETURN; } found = pdb_getsampwnam( sampass, name ); if (on( SMB_MIGRATE, ctrl )) { retval = _smb_add_user(pamh, ctrl, name, sampass, found); TALLOC_FREE(sampass); AUTH_RETURN; } if (!found) { _log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", name); retval = PAM_USER_UNKNOWN; TALLOC_FREE(sampass); sampass = NULL; AUTH_RETURN; } /* if this user does not have a password... */ if (_smb_blankpasswd( ctrl, sampass )) { TALLOC_FREE(sampass); retval = PAM_SUCCESS; AUTH_RETURN; } /* get this user's authentication token */ retval = _smb_read_password(pamh, ctrl, NULL, "Password: "******"auth: no password provided for [%s]", name); TALLOC_FREE(sampass); AUTH_RETURN; } /* verify the password of this user */ retval = _smb_verify_password( pamh, sampass, p, ctrl ); TALLOC_FREE(sampass); p = NULL; AUTH_RETURN; }
/* * Do some module- and library-wide intializations */ static void SMBC_module_init(void * punused) { bool conf_loaded = False; char *home = NULL; TALLOC_CTX *frame = talloc_stackframe(); load_case_tables(); setup_logging("libsmbclient", True); /* Here we would open the smb.conf file if needed ... */ lp_set_in_client(True); home = getenv("HOME"); if (home) { char *conf = NULL; if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) { if (lp_load(conf, True, False, False, True)) { conf_loaded = True; } else { DEBUG(5, ("Could not load config file: %s\n", conf)); } SAFE_FREE(conf); } } if (!conf_loaded) { /* * Well, if that failed, try the get_dyn_CONFIGFILE * Which points to the standard locn, and if that * fails, silently ignore it and use the internal * defaults ... */ if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) { DEBUG(5, ("Could not load config file: %s\n", get_dyn_CONFIGFILE())); } else if (home) { char *conf; /* * We loaded the global config file. Now lets * load user-specific modifications to the * global config. */ if (asprintf(&conf, "%s/.smb/smb.conf.append", home) > 0) { if (!lp_load(conf, True, False, False, False)) { DEBUG(10, ("Could not append config file: " "%s\n", conf)); } SAFE_FREE(conf); } } } load_interfaces(); /* Load the list of interfaces ... */ reopen_logs(); /* Get logging working ... */ /* * Block SIGPIPE (from lib/util_sock.c: write()) * It is not needed and should not stop execution */ BlockSignals(True, SIGPIPE); /* Create the mutex we'll use to protect initialized_ctx_count */ if (SMB_THREAD_CREATE_MUTEX("initialized_ctx_count_mutex", initialized_ctx_count_mutex) != 0) { smb_panic("SMBC_module_init: " "failed to create 'initialized_ctx_count' mutex"); } TALLOC_FREE(frame); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) { /* I - Command-line arguments */ int i; /* Looping var */ int copies; /* Number of copies */ int port; /* Port number */ char uri[1024], /* URI */ *sep, /* Pointer to separator */ *tmp, *tmp2, /* Temp pointers to do escaping */ *password; /* Password */ char *username, /* Username */ *server, /* Server name */ *printer;/* Printer name */ const char *workgroup; /* Workgroup */ FILE *fp; /* File to print */ int status = 1; /* Status of LPD job */ struct cli_state *cli; /* SMB interface */ char null_str[1]; int tries = 0; bool need_auth = true; const char *dev_uri; TALLOC_CTX *frame = talloc_stackframe(); 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) == 0) { argv++; argc--; } if (argc == 1) { /* * NEW! In CUPS 1.1 the backends are run with no arguments * to list the available devices. These can be devices * served by this backend or any other backends (i.e. you * can have an SNMP backend that is only used to enumerate * the available network printers... :) */ list_devices(); status = 0; goto done; } if (argc < 6 || argc > 7) { fprintf(stderr, "Usage: %s [DEVICE_URI] job-id user title copies options [file]\n" " The DEVICE_URI environment variable can also contain the\n" " destination printer:\n" "\n" " smb://[username:password@][workgroup/]server[:port]/printer\n", argv[0]); goto done; } /* * If we have 7 arguments, print the file named on the command-line. * Otherwise, print data from stdin... */ if (argc == 6) { /* * Print from Copy stdin to a temporary file... */ fp = stdin; copies = 1; } else if ((fp = fopen(argv[6], "rb")) == NULL) { perror("ERROR: Unable to open print file"); goto done; } else { copies = atoi(argv[4]); } /* * Find the URI... */ 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 { fputs("ERROR: No device URI found in DEVICE_URI environment variable or argv[0] !\n", stderr); goto done; } uri[sizeof(uri) - 1] = '\0'; /* * Extract the destination from the URI... */ if ((sep = strrchr_m(uri, '@')) != NULL) { tmp = uri + 6; *sep++ = '\0'; /* username is in tmp */ server = sep; /* * Extract password as needed... */ if ((tmp2 = strchr_m(tmp, ':')) != NULL) { *tmp2++ = '\0'; password = uri_unescape_alloc(tmp2); } else { password = null_str; } username = uri_unescape_alloc(tmp); } else { if ((username = getenv("AUTH_USERNAME")) == NULL) { username = null_str; } if ((password = getenv("AUTH_PASSWORD")) == NULL) { password = null_str; } server = uri + 6; } tmp = server; if ((sep = strchr_m(tmp, '/')) == NULL) { fputs("ERROR: Bad URI - need printer name!\n", stderr); goto done; } *sep++ = '\0'; tmp2 = sep; if ((sep = strchr_m(tmp2, '/')) != NULL) { /* * Convert to smb://[username:password@]workgroup/server/printer... */ *sep++ = '\0'; workgroup = uri_unescape_alloc(tmp); server = uri_unescape_alloc(tmp2); printer = uri_unescape_alloc(sep); } else { workgroup = NULL; server = uri_unescape_alloc(tmp); printer = uri_unescape_alloc(tmp2); } if ((sep = strrchr_m(server, ':')) != NULL) { *sep++ = '\0'; port = atoi(sep); } else { port = 0; } /* * Setup the SAMBA server state... */ setup_logging("smbspool", DEBUG_STDOUT); lp_set_in_client(True); /* Make sure that we tell lp_load we are */ load_case_tables(); if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, True)) { fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", get_dyn_CONFIGFILE()); goto done; } if (workgroup == NULL) { workgroup = lp_workgroup(); } load_interfaces(); do { cli = smb_connect(workgroup, server, port, printer, username, password, argv[2], &need_auth); if (cli == NULL) { if (need_auth) { exit(2); } else if (getenv("CLASS") == NULL) { fprintf(stderr, "ERROR: Unable to connect to CIFS host, will retry in 60 seconds...\n"); sleep(60); tries++; } else { fprintf(stderr, "ERROR: Unable to connect to CIFS host, trying next printer...\n"); goto done; } } } 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); goto done; } /* * Now that we are connected to the server, ignore SIGTERM so that we * can finish out any page data the driver sends (e.g. to eject the * current page... Only ignore SIGTERM if we are printing data from * stdin (otherwise you can't cancel raw jobs...) */ if (argc < 7) { CatchSignal(SIGTERM, SIG_IGN); } /* * Queue the job... */ for (i = 0; i < copies; i++) { status = smb_print(cli, argv[3] /* title */ , fp); if (status != 0) { break; } } cli_shutdown(cli); /* * Return the queue status... */ done: TALLOC_FREE(frame); return (status); }
int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags, int argc, const char **argv ) { unsigned int ctrl; int retval; const char *name; struct samu *sampass = NULL; void (*oldsig_handler)(int); /* Samba initialization. */ load_case_tables(); setup_logging( "pam_smbpass", False ); lp_set_in_client(True); ctrl = set_ctrl( flags, argc, argv ); /* get the username */ retval = pam_get_user( pamh, &name, "Username: "******"acct: could not identify user" ); } return retval; } if (on( SMB_DEBUG, ctrl )) { _log_err( LOG_DEBUG, "acct: username [%s] obtained", name ); } if (geteuid() != 0) { _log_err( LOG_DEBUG, "Cannot access samba password database, not running as root."); return PAM_AUTHINFO_UNAVAIL; } /* Getting into places that might use LDAP -- protect the app from a SIGPIPE it's not expecting */ oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN); if (!initialize_password_db(True, NULL)) { _log_err( LOG_ALERT, "Cannot access samba password database" ); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_AUTHINFO_UNAVAIL; } /* Get the user's record. */ if (!(sampass = samu_new( NULL ))) { CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); /* malloc fail. */ return nt_status_to_pam(NT_STATUS_NO_MEMORY); } if (!pdb_getsampwnam(sampass, name )) { _log_err( LOG_DEBUG, "acct: could not identify user" ); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_USER_UNKNOWN; } /* check for lookup failure */ if (!strlen(pdb_get_username(sampass)) ) { CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_USER_UNKNOWN; } if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { if (on( SMB_DEBUG, ctrl )) { _log_err( LOG_DEBUG , "acct: account %s is administratively disabled", name ); } make_remark( pamh, ctrl, PAM_ERROR_MSG , "Your account has been disabled; " "please see your system administrator." ); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_ACCT_EXPIRED; } /* TODO: support for expired passwords. */ CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_SUCCESS; }