static bool wbinfo_lookupsid(const char *sid_str) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainSid sid; char *domain; char *name; enum wbcSidType type; /* Send off request */ wbc_status = wbcStringToSid(sid_str, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } wbc_status = wbcLookupSid(&sid, &domain, &name, &type); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } /* Display response */ d_printf("%s%c%s %d\n", domain, winbind_separator(), name, type); return true; }
static bool parse_wbinfo_domain_user(const char *domuser, fstring domain, fstring user) { char *p = strchr(domuser,winbind_separator()); if (!p) { /* Maybe it was a UPN? */ if ((p = strchr(domuser, '@')) != NULL) { fstrcpy(domain, ""); fstrcpy(user, domuser); return true; } fstrcpy(user, domuser); fstrcpy(domain, get_winbind_domain()); return true; } fstrcpy(user, p+1); fstrcpy(domain, domuser); domain[PTR_DIFF(p, domuser)] = 0; strupper_m(domain); return true; }
static BOOL parse_ntlm_auth_domain_user(const char *domuser, fstring domain, fstring user) { char *p = strchr(domuser,winbind_separator()); if (!p) { return False; } fstrcpy(user, p+1); fstrcpy(domain, domuser); domain[PTR_DIFF(p, domuser)] = 0; strupper_m(domain); return True; }
static bool wbinfo_lookupsid(char *sid) { struct winbindd_request request; struct winbindd_response response; ZERO_STRUCT(request); ZERO_STRUCT(response); /* Send off request */ fstrcpy(request.data.sid, sid); if (winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response) != NSS_STATUS_SUCCESS) return false; /* Display response */ d_printf("%s%c%s %s\n", response.data.name.dom_name, winbind_separator(), response.data.name.name, sid_type_lookup(response.data.name.type)); return true; }
int main(int argc, const char **argv) { int opt; static const char *helper_protocol; static int diagnostics; static const char *hex_challenge; static const char *hex_lm_response; static const char *hex_nt_response; poptContext pc; /* NOTE: DO NOT change this interface without considering the implications! This is an external interface, which other programs will use to interact with this helper. */ /* We do not use single-letter command abbreviations, because they harm future interface stability. */ struct poptOption long_options[] = { POPT_AUTOHELP { "helper-protocol", 0, POPT_ARG_STRING, &helper_protocol, OPT_DOMAIN, "operate as a stdio-based helper", "helper protocol to use"}, { "username", 0, POPT_ARG_STRING, &opt_username, OPT_USERNAME, "username"}, { "domain", 0, POPT_ARG_STRING, &opt_domain, OPT_DOMAIN, "domain name"}, { "workstation", 0, POPT_ARG_STRING, &opt_workstation, OPT_WORKSTATION, "workstation"}, { "challenge", 0, POPT_ARG_STRING, &hex_challenge, OPT_CHALLENGE, "challenge (HEX encoded)"}, { "lm-response", 0, POPT_ARG_STRING, &hex_lm_response, OPT_LM, "LM Response to the challenge (HEX encoded)"}, { "nt-response", 0, POPT_ARG_STRING, &hex_nt_response, OPT_NT, "NT or NTLMv2 Response to the challenge (HEX encoded)"}, { "password", 0, POPT_ARG_STRING, &opt_password, OPT_PASSWORD, "User's plaintext password"}, { "request-lm-key", 0, POPT_ARG_NONE, &request_lm_key, OPT_LM_KEY, "Retrieve LM session key"}, { "request-nt-key", 0, POPT_ARG_NONE, &request_user_session_key, OPT_USER_SESSION_KEY, "Retrieve User (NT) session key"}, { "diagnostics", 0, POPT_ARG_NONE, &diagnostics, OPT_DIAGNOSTICS, "Perform diagnostics on the authentictaion chain"}, { "require-membership-of", 0, POPT_ARG_STRING, &require_membership_of, OPT_REQUIRE_MEMBERSHIP, "Require that a user be a member of this group (either name or SID) for authentication to succeed" }, POPT_COMMON_SAMBA POPT_TABLEEND }; /* Samba client initialisation */ load_case_tables(); dbf = x_stderr; /* Samba client initialisation */ if (!lp_load(dyn_CONFIGFILE, True, False, False, True)) { d_fprintf(stderr, "ntlm_auth: error opening config file %s. Error was %s\n", dyn_CONFIGFILE, strerror(errno)); exit(1); } /* Parse options */ pc = poptGetContext("ntlm_auth", argc, argv, long_options, 0); /* Parse command line options */ if (argc == 1) { poptPrintHelp(pc, stderr, 0); return 1; } pc = poptGetContext(NULL, argc, (const char **)argv, long_options, POPT_CONTEXT_KEEP_FIRST); while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_CHALLENGE: opt_challenge = strhex_to_data_blob(NULL, hex_challenge); if (opt_challenge.length != 8) { x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n", hex_challenge, (int)opt_challenge.length); exit(1); } break; case OPT_LM: opt_lm_response = strhex_to_data_blob(NULL, hex_lm_response); if (opt_lm_response.length != 24) { x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n", hex_lm_response, (int)opt_lm_response.length); exit(1); } break; case OPT_NT: opt_nt_response = strhex_to_data_blob(NULL, hex_nt_response); if (opt_nt_response.length < 24) { x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n", hex_nt_response, (int)opt_nt_response.length); exit(1); } break; case OPT_REQUIRE_MEMBERSHIP: if (StrnCaseCmp("S-", require_membership_of, 2) == 0) { require_membership_of_sid = require_membership_of; } break; } } if (opt_username) { char *domain = SMB_STRDUP(opt_username); char *p = strchr_m(domain, *lp_winbind_separator()); if (p) { opt_username = p+1; *p = '\0'; if (opt_domain && !strequal(opt_domain, domain)) { x_fprintf(x_stderr, "Domain specified in username (%s) " "doesn't match specified domain (%s)!\n\n", domain, opt_domain); poptPrintHelp(pc, stderr, 0); exit(1); } opt_domain = domain; } else { SAFE_FREE(domain); } } if (opt_domain == NULL || !*opt_domain) { opt_domain = get_winbind_domain(); } if (opt_workstation == NULL) { opt_workstation = ""; } if (helper_protocol) { int i; for (i=0; i<NUM_HELPER_MODES; i++) { if (strcmp(helper_protocol, stdio_helper_protocols[i].name) == 0) { squid_stream(stdio_helper_protocols[i].mode, stdio_helper_protocols[i].fn); exit(0); } } x_fprintf(x_stderr, "unknown helper protocol [%s]\n\nValid helper protools:\n\n", helper_protocol); for (i=0; i<NUM_HELPER_MODES; i++) { x_fprintf(x_stderr, "%s\n", stdio_helper_protocols[i].name); } exit(1); } if (!opt_username || !*opt_username) { x_fprintf(x_stderr, "username must be specified!\n\n"); poptPrintHelp(pc, stderr, 0); exit(1); } if (opt_challenge.length) { if (!check_auth_crap()) { exit(1); } exit(0); } if (!opt_password) { opt_password = getpass("password: "******"%s%c%s", opt_domain, winbind_separator(), opt_username); if (!check_plaintext_auth(user, opt_password, True)) { return 1; } } /* Exit code */ poptFreeContext(pc); return 0; }
static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { char *request, *parameter; static DATA_BLOB challenge; static DATA_BLOB lm_response; static DATA_BLOB nt_response; static char *full_username; static char *username; static char *domain; static char *plaintext_password; static BOOL ntlm_server_1_user_session_key; static BOOL ntlm_server_1_lm_session_key; if (strequal(buf, ".")) { if (!full_username && !username) { x_fprintf(x_stdout, "Error: No username supplied!\n"); } else if (plaintext_password) { /* handle this request as plaintext */ if (!full_username) { if (asprintf(&full_username, "%s%c%s", domain, winbind_separator(), username) == -1) { x_fprintf(x_stdout, "Error: Out of memory in asprintf!\n.\n"); return; } } if (check_plaintext_auth(full_username, plaintext_password, False)) { x_fprintf(x_stdout, "Authenticated: Yes\n"); } else { x_fprintf(x_stdout, "Authenticated: No\n"); } } else if (!lm_response.data && !nt_response.data) { x_fprintf(x_stdout, "Error: No password supplied!\n"); } else if (!challenge.data) { x_fprintf(x_stdout, "Error: No lanman-challenge supplied!\n"); } else { char *error_string = NULL; uchar lm_key[8]; uchar user_session_key[16]; uint32 flags = 0; if (full_username && !username) { fstring fstr_user; fstring fstr_domain; if (!parse_ntlm_auth_domain_user(full_username, fstr_user, fstr_domain)) { /* username might be 'tainted', don't print into our new-line deleimianted stream */ x_fprintf(x_stdout, "Error: Could not parse into domain and username\n"); } SAFE_FREE(username); SAFE_FREE(domain); username = smb_xstrdup(fstr_user); domain = smb_xstrdup(fstr_domain); } if (!domain) { domain = smb_xstrdup(get_winbind_domain()); } if (ntlm_server_1_lm_session_key) flags |= WBFLAG_PAM_LMKEY; if (ntlm_server_1_user_session_key) flags |= WBFLAG_PAM_USER_SESSION_KEY; if (!NT_STATUS_IS_OK( contact_winbind_auth_crap(username, domain, global_myname(), &challenge, &lm_response, &nt_response, flags, lm_key, user_session_key, &error_string, NULL))) { x_fprintf(x_stdout, "Authenticated: No\n"); x_fprintf(x_stdout, "Authentication-Error: %s\n.\n", error_string); SAFE_FREE(error_string); } else { static char zeros[16]; char *hex_lm_key; char *hex_user_session_key; x_fprintf(x_stdout, "Authenticated: Yes\n"); if (ntlm_server_1_lm_session_key && (memcmp(zeros, lm_key, sizeof(lm_key)) != 0)) { hex_lm_key = hex_encode(NULL, (const unsigned char *)lm_key, sizeof(lm_key)); x_fprintf(x_stdout, "LANMAN-Session-Key: %s\n", hex_lm_key); TALLOC_FREE(hex_lm_key); } if (ntlm_server_1_user_session_key && (memcmp(zeros, user_session_key, sizeof(user_session_key)) != 0)) { hex_user_session_key = hex_encode(NULL, (const unsigned char *)user_session_key, sizeof(user_session_key)); x_fprintf(x_stdout, "User-Session-Key: %s\n", hex_user_session_key); TALLOC_FREE(hex_user_session_key); } } } /* clear out the state */ challenge = data_blob(NULL, 0); nt_response = data_blob(NULL, 0); lm_response = data_blob(NULL, 0); SAFE_FREE(full_username); SAFE_FREE(username); SAFE_FREE(domain); SAFE_FREE(plaintext_password); ntlm_server_1_user_session_key = False; ntlm_server_1_lm_session_key = False; x_fprintf(x_stdout, ".\n"); return; } request = buf; /* Indicates a base64 encoded structure */ parameter = strstr_m(request, ":: "); if (!parameter) { parameter = strstr_m(request, ": "); if (!parameter) { DEBUG(0, ("Parameter not found!\n")); x_fprintf(x_stdout, "Error: Parameter not found!\n.\n"); return; } parameter[0] ='\0'; parameter++; parameter[0] ='\0'; parameter++; } else { parameter[0] ='\0'; parameter++; parameter[0] ='\0'; parameter++; parameter[0] ='\0'; parameter++; base64_decode_inplace(parameter); } if (strequal(request, "LANMAN-Challenge")) { challenge = strhex_to_data_blob(NULL, parameter); if (challenge.length != 8) { x_fprintf(x_stdout, "Error: hex decode of %s failed! (got %d bytes, expected 8)\n.\n", parameter, (int)challenge.length); challenge = data_blob(NULL, 0); } } else if (strequal(request, "NT-Response")) { nt_response = strhex_to_data_blob(NULL, parameter); if (nt_response.length < 24) { x_fprintf(x_stdout, "Error: hex decode of %s failed! (only got %d bytes, needed at least 24)\n.\n", parameter, (int)nt_response.length); nt_response = data_blob(NULL, 0); } } else if (strequal(request, "LANMAN-Response")) { lm_response = strhex_to_data_blob(NULL, parameter); if (lm_response.length != 24) { x_fprintf(x_stdout, "Error: hex decode of %s failed! (got %d bytes, expected 24)\n.\n", parameter, (int)lm_response.length); lm_response = data_blob(NULL, 0); } } else if (strequal(request, "Password")) { plaintext_password = smb_xstrdup(parameter); } else if (strequal(request, "NT-Domain")) { domain = smb_xstrdup(parameter); } else if (strequal(request, "Username")) { username = smb_xstrdup(parameter); } else if (strequal(request, "Full-Username")) { full_username = smb_xstrdup(parameter); } else if (strequal(request, "Request-User-Session-Key")) { ntlm_server_1_user_session_key = strequal(parameter, "Yes"); } else if (strequal(request, "Request-LanMan-Session-Key")) { ntlm_server_1_lm_session_key = strequal(parameter, "Yes"); } else { x_fprintf(x_stdout, "Error: Unknown request %s\n.\n", request); } }