X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=nsswitch%2Fwbinfo.c;h=c456f6eb32903cebb7b6f0ba76896e5269713eb1;hp=813846f138833b51d87317743936d4beebb27264;hb=c36cf69d5911b86d73a495308c1bed14004b0659;hpb=bc0e0a4c69d11fbdb61b1edc1e8d088090807249 diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c index 813846f1388..c456f6eb329 100644 --- a/nsswitch/wbinfo.c +++ b/nsswitch/wbinfo.c @@ -5,6 +5,7 @@ Copyright (C) Tim Potter 2000-2003 Copyright (C) Andrew Bartlett 2002-2007 + Copyright (C) Volker Lendecke 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,11 +24,9 @@ #include "includes.h" #include "winbind_client.h" #include "libwbclient/wbclient.h" -#include "lib/popt/popt.h" #include "../libcli/auth/libcli_auth.h" -#if !(_SAMBA_VERSION_) < 4 #include "lib/cmdline/popt_common.h" -#endif +#include "lib/afs/afs_settoken.h" #ifdef DBGC_CLASS #undef DBGC_CLASS @@ -46,7 +45,7 @@ static struct wbcInterfaceDetails *init_interface_details(void) wbc_status = wbcInterfaceDetails(&details); if (!WBC_ERROR_IS_OK(wbc_status)) { d_fprintf(stderr, "could not obtain winbind interface " - "details!\n"); + "details: %s\n", wbcErrorString(wbc_status)); } return details; @@ -118,7 +117,8 @@ static bool parse_wbinfo_domain_user(const char *domuser, fstring domain, if (!p) { /* Maybe it was a UPN? */ - if ((p = strchr(domuser, '@')) != NULL) { + p = strchr(domuser, '@'); + if (p != NULL) { fstrcpy(domain, ""); fstrcpy(user, domuser); return true; @@ -132,7 +132,6 @@ static bool parse_wbinfo_domain_user(const char *domuser, fstring domain, fstrcpy(user, p+1); fstrcpy(domain, domuser); domain[PTR_DIFF(p, domuser)] = 0; - strupper_m(domain); return true; } @@ -171,6 +170,8 @@ static bool wbinfo_get_userinfo(char *user) wbc_status = wbcGetpwnam(user, &pwd); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcGetpwnam: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -183,6 +184,8 @@ static bool wbinfo_get_userinfo(char *user) pwd->pw_dir, pwd->pw_shell); + wbcFreeMemory(pwd); + return true; } @@ -194,6 +197,8 @@ static bool wbinfo_get_uidinfo(int uid) wbc_status = wbcGetpwuid(uid, &pwd); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcGetpwuid: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -206,6 +211,8 @@ static bool wbinfo_get_uidinfo(int uid) pwd->pw_dir, pwd->pw_shell); + wbcFreeMemory(pwd); + return true; } @@ -218,6 +225,8 @@ static bool wbinfo_get_user_sidinfo(const char *sid_str) wbc_status = wbcStringToSid(sid_str, &sid); wbc_status = wbcGetpwsid(&sid, &pwd); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcGetpwsid: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -230,6 +239,8 @@ static bool wbinfo_get_user_sidinfo(const char *sid_str) pwd->pw_dir, pwd->pw_shell); + wbcFreeMemory(pwd); + return true; } @@ -243,6 +254,8 @@ static bool wbinfo_get_groupinfo(const char *group) wbc_status = wbcGetgrnam(group, &grp); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcGetgrnam: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -272,6 +285,8 @@ static bool wbinfo_get_gidinfo(int gid) wbc_status = wbcGetgrgid(gid, &grp); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcGetgrgid: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -305,6 +320,8 @@ static bool wbinfo_get_usergroups(const char *user) wbc_status = wbcGetGroups(user, &num_groups, &groups); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcGetGroups: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -330,23 +347,22 @@ static bool wbinfo_get_usersids(const char *user_sid_str) wbc_status = wbcStringToSid(user_sid_str, &user_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcStringToSid: %s\n", + wbcErrorString(wbc_status)); return false; } wbc_status = wbcLookupUserSids(&user_sid, false, &num_sids, &sids); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcLookupUserSids: %s\n", + wbcErrorString(wbc_status)); return false; } for (i = 0; i < num_sids; i++) { - char *str = NULL; - wbc_status = wbcSidToString(&sids[i], &str); - if (!WBC_ERROR_IS_OK(wbc_status)) { - wbcFreeMemory(sids); - return false; - } + char str[WBC_SID_STRING_BUFLEN]; + wbcSidToStringBuf(&sids[i], str, sizeof(str)); d_printf("%s\n", str); - wbcFreeMemory(str); } wbcFreeMemory(sids); @@ -365,23 +381,22 @@ static bool wbinfo_get_userdomgroups(const char *user_sid_str) wbc_status = wbcStringToSid(user_sid_str, &user_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcStringToSid: %s\n", + wbcErrorString(wbc_status)); return false; } wbc_status = wbcLookupUserSids(&user_sid, true, &num_sids, &sids); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcLookupUserSids: %s\n", + wbcErrorString(wbc_status)); return false; } for (i = 0; i < num_sids; i++) { - char *str = NULL; - wbc_status = wbcSidToString(&sids[i], &str); - if (!WBC_ERROR_IS_OK(wbc_status)) { - wbcFreeMemory(sids); - return false; - } + char str[WBC_SID_STRING_BUFLEN]; + wbcSidToStringBuf(&sids[i], str, sizeof(str)); d_printf("%s\n", str); - wbcFreeMemory(str); } wbcFreeMemory(sids); @@ -398,7 +413,7 @@ static bool wbinfo_get_sidaliases(const char *domain, struct wbcDomainSid user_sid; uint32_t *alias_rids = NULL; uint32_t num_alias_rids; - char *domain_sid_str = NULL; + char domain_sid_str[WBC_SID_STRING_BUFLEN]; /* Send request */ if ((domain == NULL) || (strequal(domain, ".")) || @@ -410,8 +425,8 @@ static bool wbinfo_get_sidaliases(const char *domain, wbc_status = wbcDomainInfo(domain, &dinfo); if (!WBC_ERROR_IS_OK(wbc_status)) { - d_printf("wbcDomainInfo(%s) failed: %s\n", domain, - wbcErrorString(wbc_status)); + d_fprintf(stderr, "wbcDomainInfo(%s) failed: %s\n", domain, + wbcErrorString(wbc_status)); goto done; } wbc_status = wbcStringToSid(user_sid_str, &user_sid); @@ -425,10 +440,7 @@ static bool wbinfo_get_sidaliases(const char *domain, goto done; } - wbc_status = wbcSidToString(&dinfo->sid, &domain_sid_str); - if (!WBC_ERROR_IS_OK(wbc_status)) { - goto done; - } + wbcSidToStringBuf(&dinfo->sid, domain_sid_str, sizeof(domain_sid_str)); for (i = 0; i < num_alias_rids; i++) { d_printf("%s-%d\n", domain_sid_str, alias_rids[i]); @@ -437,12 +449,7 @@ static bool wbinfo_get_sidaliases(const char *domain, wbcFreeMemory(alias_rids); done: - if (domain_sid_str) { - wbcFreeMemory(domain_sid_str); - } - if (dinfo) { - wbcFreeMemory(dinfo); - } + wbcFreeMemory(dinfo); return (WBC_ERR_SUCCESS == wbc_status); } @@ -456,6 +463,8 @@ static bool wbinfo_wins_byname(const char *name) wbc_status = wbcResolveWinsByName(name, &ip); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcResolveWinsByName: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -477,6 +486,8 @@ static bool wbinfo_wins_byip(const char *ip) wbc_status = wbcResolveWinsByIP(ip, &name); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcResolveWinsByIP: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -501,11 +512,13 @@ static bool wbinfo_list_domains(bool list_all_domains, bool verbose) wbc_status = wbcListTrusts(&domain_list, &num_domains); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcListTrusts: %s\n", + wbcErrorString(wbc_status)); return false; } if (print_all) { - d_printf("%-16s%-24s%-12s%-12s%-5s%-5s\n", + d_printf("%-16s%-65s%-12s%-12s%-5s%-5s\n", "Domain Name", "DNS Domain", "Trust Type", "Transitive", "In", "Out"); } @@ -519,11 +532,30 @@ static bool wbinfo_list_domains(bool list_all_domains, bool verbose) continue; } - d_printf("%-24s", domain_list[i].dns_name); + d_printf("%-65s", domain_list[i].dns_name); switch(domain_list[i].trust_type) { case WBC_DOMINFO_TRUSTTYPE_NONE: - d_printf("None "); + if (domain_list[i].trust_routing != NULL) { + d_printf("%s\n", domain_list[i].trust_routing); + } else { + d_printf("None\n"); + } + continue; + case WBC_DOMINFO_TRUSTTYPE_LOCAL: + d_printf("Local\n"); + continue; + case WBC_DOMINFO_TRUSTTYPE_RWDC: + d_printf("RWDC\n"); + continue; + case WBC_DOMINFO_TRUSTTYPE_RODC: + d_printf("RODC\n"); + continue; + case WBC_DOMINFO_TRUSTTYPE_PDC: + d_printf("PDC\n"); + continue; + case WBC_DOMINFO_TRUSTTYPE_WKSTA: + d_printf("Workstation "); break; case WBC_DOMINFO_TRUSTTYPE_FOREST: d_printf("Forest "); @@ -557,6 +589,8 @@ static bool wbinfo_list_domains(bool list_all_domains, bool verbose) d_printf("\n"); } + wbcFreeMemory(domain_list); + return true; } @@ -587,6 +621,8 @@ static bool wbinfo_show_onlinestatus(const char *domain) wbc_status = wbcListTrusts(&domain_list, &num_domains); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcListTrusts: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -604,9 +640,11 @@ static bool wbinfo_show_onlinestatus(const char *domain) d_printf("%s : %s\n", domain_list[i].short_name, - is_offline ? "offline" : "online" ); + is_offline ? "no active connection" : "active connection" ); } + wbcFreeMemory(domain_list); + return true; } @@ -617,7 +655,7 @@ static bool wbinfo_domain_info(const char *domain) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainInfo *dinfo = NULL; - char *sid_str = NULL; + char sid_str[WBC_SID_STRING_BUFLEN]; if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')){ domain = get_winbind_domain(); @@ -627,14 +665,12 @@ static bool wbinfo_domain_info(const char *domain) wbc_status = wbcDomainInfo(domain, &dinfo); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcDomainInfo: %s\n", + wbcErrorString(wbc_status)); return false; } - wbc_status = wbcSidToString(&dinfo->sid, &sid_str); - if (!WBC_ERROR_IS_OK(wbc_status)) { - wbcFreeMemory(dinfo); - return false; - } + wbcSidToStringBuf(&dinfo->sid, sid_str, sizeof(sid_str)); /* Display response */ @@ -653,7 +689,6 @@ static bool wbinfo_domain_info(const char *domain) (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_PRIMARY) ? "Yes" : "No"); - wbcFreeMemory(sid_str); wbcFreeMemory(dinfo); return true; @@ -672,7 +707,7 @@ static bool wbinfo_getdcname(const char *domain_name) /* Send request */ - if (winbindd_request_response(WINBINDD_GETDCNAME, &request, + if (winbindd_request_response(NULL, WINBINDD_GETDCNAME, &request, &response) != NSS_STATUS_SUCCESS) { d_fprintf(stderr, "Could not get dc name for %s\n",domain_name); return false; @@ -688,58 +723,162 @@ static bool wbinfo_getdcname(const char *domain_name) /* Find a DC */ static bool wbinfo_dsgetdcname(const char *domain_name, uint32_t flags) { - struct winbindd_request request; - struct winbindd_response response; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainControllerInfoEx *dc_info; + char *str = NULL; - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbc_status = wbcLookupDomainControllerEx(domain_name, NULL, NULL, + flags | DS_DIRECTORY_SERVICE_REQUIRED, + &dc_info); + if (!WBC_ERROR_IS_OK(wbc_status)) { + printf("Could not find dc for %s\n", domain_name); + return false; + } - fstrcpy(request.data.dsgetdcname.domain_name, domain_name); - request.data.dsgetdcname.flags = flags; + wbcGuidToString(dc_info->domain_guid, &str); - request.flags |= DS_DIRECTORY_SERVICE_REQUIRED; + d_printf("%s\n", dc_info->dc_unc); + d_printf("%s\n", dc_info->dc_address); + d_printf("%d\n", dc_info->dc_address_type); + d_printf("%s\n", str); + d_printf("%s\n", dc_info->domain_name); + d_printf("%s\n", dc_info->forest_name); + d_printf("0x%08x\n", dc_info->dc_flags); + d_printf("%s\n", dc_info->dc_site_name); + d_printf("%s\n", dc_info->client_site_name); - /* Send request */ + wbcFreeMemory(str); + wbcFreeMemory(dc_info); - if (winbindd_request_response(WINBINDD_DSGETDCNAME, &request, - &response) != NSS_STATUS_SUCCESS) { - d_fprintf(stderr, "Could not find dc for %s\n", domain_name); + return true; +} + +/* Check trust account password */ + +static bool wbinfo_check_secret(const char *domain) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcAuthErrorInfo *error = NULL; + const char *domain_name; + + if (domain) { + domain_name = domain; + } else { + domain_name = get_winbind_domain(); + } + + wbc_status = wbcCheckTrustCredentials(domain_name, &error); + + d_printf("checking the trust secret for domain %s via RPC calls %s\n", + domain_name, + WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); + + if (wbc_status == WBC_ERR_AUTH_ERROR) { + d_fprintf(stderr, "wbcCheckTrustCredentials(%s): error code was %s (0x%x)\n", + domain_name, error->nt_string, error->nt_status); + wbcFreeMemory(error); + } + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcCheckTrustCredentials: " + "%s\n", wbcErrorString(wbc_status)); return false; } - /* Display response */ + return true; +} + +/* Find the currently connected DCs */ - d_printf("%s\n", response.data.dsgetdcname.dc_unc); - d_printf("%s\n", response.data.dsgetdcname.dc_address); - d_printf("%d\n", response.data.dsgetdcname.dc_address_type); - d_printf("%s\n", response.data.dsgetdcname.domain_guid); - d_printf("%s\n", response.data.dsgetdcname.domain_name); - d_printf("%s\n", response.data.dsgetdcname.forest_name); - d_printf("0x%08x\n", response.data.dsgetdcname.dc_flags); - d_printf("%s\n", response.data.dsgetdcname.dc_site_name); - d_printf("%s\n", response.data.dsgetdcname.client_site_name); +static bool wbinfo_dc_info(const char *domain_name) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + size_t i, num_dcs; + const char **dc_names, **dc_ips; + + wbc_status = wbcDcInfo(domain_name, &num_dcs, + &dc_names, &dc_ips); + if (!WBC_ERROR_IS_OK(wbc_status)) { + printf("Could not find dc info %s\n", + domain_name ? domain_name : "our domain"); + return false; + } + + for (i=0; int_string, error->nt_status); + wbcFreeMemory(error); + } + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcChangeTrustCredentials: " + "%s\n", wbcErrorString(wbc_status)); + return false; + } - wbc_status = wbcCheckTrustCredentials(NULL, &error); + return true; +} + +/* Check DC connection */ - d_printf("checking the trust secret via RPC calls %s\n", +static bool wbinfo_ping_dc(const char *domain) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcAuthErrorInfo *error = NULL; + char *dcname = NULL; + + const char *domain_name; + + if (domain) { + domain_name = domain; + } else { + domain_name = get_winbind_domain(); + } + + wbc_status = wbcPingDc2(domain_name, &error, &dcname); + + d_printf("checking the NETLOGON for domain[%s] dc connection to \"%s\" %s\n", + domain_name ? domain_name : "", + dcname ? dcname : "", WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); + wbcFreeMemory(dcname); if (wbc_status == WBC_ERR_AUTH_ERROR) { - d_fprintf(stderr, "error code was %s (0x%x)\n", - error->nt_string, error->nt_status); + d_fprintf(stderr, "wbcPingDc2(%s): error code was %s (0x%x)\n", + domain_name, error->nt_string, error->nt_status); wbcFreeMemory(error); + return false; } if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcPingDc: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -752,26 +891,23 @@ static bool wbinfo_uid_to_sid(uid_t uid) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainSid sid; - char *sid_str = NULL; + char sid_str[WBC_SID_STRING_BUFLEN]; /* Send request */ wbc_status = wbcUidToSid(uid, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcUidToSid: %s\n", + wbcErrorString(wbc_status)); return false; } - wbc_status = wbcSidToString(&sid, &sid_str); - if (!WBC_ERROR_IS_OK(wbc_status)) { - return false; - } + wbcSidToStringBuf(&sid, sid_str, sizeof(sid_str)); /* Display response */ d_printf("%s\n", sid_str); - wbcFreeMemory(sid_str); - return true; } @@ -781,26 +917,23 @@ static bool wbinfo_gid_to_sid(gid_t gid) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainSid sid; - char *sid_str = NULL; + char sid_str[WBC_SID_STRING_BUFLEN]; /* Send request */ wbc_status = wbcGidToSid(gid, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcGidToSid: %s\n", + wbcErrorString(wbc_status)); return false; } - wbc_status = wbcSidToString(&sid, &sid_str); - if (!WBC_ERROR_IS_OK(wbc_status)) { - return false; - } + wbcSidToStringBuf(&sid, sid_str, sizeof(sid_str)); /* Display response */ d_printf("%s\n", sid_str); - wbcFreeMemory(sid_str); - return true; } @@ -816,11 +949,15 @@ static bool wbinfo_sid_to_uid(const char *sid_str) wbc_status = wbcStringToSid(sid_str, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcStringToSid: %s\n", + wbcErrorString(wbc_status)); return false; } wbc_status = wbcSidToUid(&sid, &uid); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcSidToUid: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -841,11 +978,15 @@ static bool wbinfo_sid_to_gid(const char *sid_str) wbc_status = wbcStringToSid(sid_str, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcStringToSid: %s\n", + wbcErrorString(wbc_status)); return false; } wbc_status = wbcSidToGid(&sid, &gid); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcSidToGid: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -856,6 +997,149 @@ static bool wbinfo_sid_to_gid(const char *sid_str) return true; } +static bool wbinfo_sids_to_unix_ids(const char *arg) +{ + char sidstr[WBC_SID_STRING_BUFLEN]; + struct wbcDomainSid *sids; + struct wbcUnixId *unix_ids; + int i, num_sids; + const char *p; + wbcErr wbc_status; + + + num_sids = 0; + sids = NULL; + p = arg; + + while (next_token(&p, sidstr, LIST_SEP, sizeof(sidstr))) { + sids = talloc_realloc(talloc_tos(), sids, struct wbcDomainSid, + num_sids+1); + if (sids == NULL) { + d_fprintf(stderr, "talloc failed\n"); + return false; + } + wbc_status = wbcStringToSid(sidstr, &sids[num_sids]); + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "wbcSidToString(%s) failed: %s\n", + sidstr, wbcErrorString(wbc_status)); + TALLOC_FREE(sids); + return false; + } + num_sids += 1; + } + + unix_ids = talloc_array(talloc_tos(), struct wbcUnixId, num_sids); + if (unix_ids == NULL) { + TALLOC_FREE(sids); + return false; + } + + wbc_status = wbcSidsToUnixIds(sids, num_sids, unix_ids); + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "wbcSidsToUnixIds failed: %s\n", + wbcErrorString(wbc_status)); + TALLOC_FREE(sids); + return false; + } + + for (i=0; i uid %d\n", sidstr, unix_ids[i].id.uid); + break; + case WBC_ID_TYPE_GID: + d_printf("%s -> gid %d\n", sidstr, unix_ids[i].id.gid); + break; + case WBC_ID_TYPE_BOTH: + d_printf("%s -> uid/gid %d\n", sidstr, unix_ids[i].id.uid); + break; + default: + d_printf("%s -> unmapped\n", sidstr); + break; + } + } + + TALLOC_FREE(sids); + TALLOC_FREE(unix_ids); + + return true; +} + +static bool wbinfo_xids_to_sids(const char *arg) +{ + fstring idstr; + struct wbcUnixId *xids = NULL; + struct wbcDomainSid *sids; + wbcErr wbc_status; + int num_xids = 0; + const char *p; + int i; + + p = arg; + + while (next_token(&p, idstr, LIST_SEP, sizeof(idstr))) { + xids = talloc_realloc(talloc_tos(), xids, struct wbcUnixId, + num_xids+1); + if (xids == NULL) { + d_fprintf(stderr, "talloc failed\n"); + return false; + } + + switch (idstr[0]) { + case 'u': + xids[num_xids] = (struct wbcUnixId) { + .type = WBC_ID_TYPE_UID, + .id.uid = atoi(&idstr[1]) + }; + break; + case 'g': + xids[num_xids] = (struct wbcUnixId) { + .type = WBC_ID_TYPE_GID, + .id.gid = atoi(&idstr[1]) + }; + break; + default: + d_fprintf(stderr, "%s is an invalid id\n", idstr); + TALLOC_FREE(xids); + return false; + } + num_xids += 1; + } + + sids = talloc_array(talloc_tos(), struct wbcDomainSid, num_xids); + if (sids == NULL) { + d_fprintf(stderr, "talloc failed\n"); + TALLOC_FREE(xids); + return false; + } + + wbc_status = wbcUnixIdsToSids(xids, num_xids, sids); + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "wbcUnixIdsToSids failed: %s\n", + wbcErrorString(wbc_status)); + TALLOC_FREE(sids); + TALLOC_FREE(xids); + return false; + } + + for (i=0; isid, num_rids, rids, - (const char **)&domain_name, &names, &types); + &p, &names, &types); if (!WBC_ERROR_IS_OK(wbc_status)) { d_printf("winbind_lookup_rids failed: %s\n", wbcErrorString(wbc_status)); goto done; } + domain_name = discard_const_p(char, p); d_printf("Domain: %s\n", domain_name); for (i=0; i= num_domains) { + domain = ""; + } else if (names[i].domain_index < 0) { + domain = ""; + } else { + domain = domains[names[i].domain_index].short_name; + } + + if (names[i].type == WBC_SID_NAME_DOMAIN) { + d_printf("%s -> %s %d\n", sidstr, + domain, + names[i].type); + } else { + d_printf("%s -> %s%c%s %d\n", sidstr, + domain, + winbind_separator(), + names[i].name, names[i].type); + } } - TALLOC_FREE(mem_ctx); - return ret; + wbcFreeMemory(names); + wbcFreeMemory(domains); + return true; } /* Convert string to sid */ @@ -1148,7 +1534,7 @@ static bool wbinfo_lookupname(const char *full_name) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainSid sid; - char *sid_str; + char sid_str[WBC_SID_STRING_BUFLEN]; enum wbcSidType type; fstring domain_name; fstring account_name; @@ -1161,20 +1547,17 @@ static bool wbinfo_lookupname(const char *full_name) wbc_status = wbcLookupName(domain_name, account_name, &sid, &type); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcLookupName: %s\n", + wbcErrorString(wbc_status)); return false; } - wbc_status = wbcSidToString(&sid, &sid_str); - if (!WBC_ERROR_IS_OK(wbc_status)) { - return false; - } + wbcSidToStringBuf(&sid, sid_str, sizeof(sid_str)); /* Display response */ d_printf("%s %s (%d)\n", sid_str, wbcSidTypeString(type), type); - wbcFreeMemory(sid_str); - return true; } @@ -1183,7 +1566,8 @@ static char *wbinfo_prompt_pass(TALLOC_CTX *mem_ctx, const char *username) { char *prompt; - const char *ret = NULL; + char buf[1024] = {0}; + int rc; prompt = talloc_asprintf(mem_ctx, "Enter %s's ", username); if (!prompt) { @@ -1200,10 +1584,13 @@ static char *wbinfo_prompt_pass(TALLOC_CTX *mem_ctx, return NULL; } - ret = getpass(prompt); + rc = samba_getpass(prompt, buf, sizeof(buf), false, false); TALLOC_FREE(prompt); + if (rc < 0) { + return NULL; + } - return talloc_strdup(mem_ctx, ret); + return talloc_strdup(mem_ctx, buf); } /* Authenticate a user with a plaintext password */ @@ -1253,6 +1640,8 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags) (uint8_t *)&flags, sizeof(flags)); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcAddNamedBlob: %s\n", + wbcErrorString(wbc_status)); goto done; } @@ -1263,6 +1652,8 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags) (uint8_t *)&uid, sizeof(uid)); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcAddNamedBlob: %s\n", + wbcErrorString(wbc_status)); goto done; } @@ -1273,6 +1664,8 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags) (uint8_t *)local_cctype, strlen(cctype)+1); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcAddNamedBlob: %s\n", + wbcErrorString(wbc_status)); goto done; } @@ -1285,8 +1678,9 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags) if (error) { d_fprintf(stderr, - "error code was %s (0x%x)\nerror messsage was: %s\n", - error->nt_string, + "wbcLogonUser(%s): error code was %s (0x%x)\n" + "error message was: %s\n", + params.username, error->nt_string, error->nt_status, error->display_string); } @@ -1318,7 +1712,6 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags) } done: - TALLOC_FREE(frame); wbcFreeMemory(params.blobs); return WBC_ERROR_IS_OK(wbc_status); @@ -1357,14 +1750,12 @@ static bool wbinfo_auth(char *username) #if 0 if (response.data.auth.nt_status) d_fprintf(stderr, - "error code was %s (0x%x)\nerror messsage was: %s\n", + "error code was %s (0x%x)\nerror message was: %s\n", response.data.auth.nt_status_string, response.data.auth.nt_status, response.data.auth.error_string); #endif - TALLOC_FREE(frame); - return WBC_ERROR_IS_OK(wbc_status); } @@ -1410,21 +1801,31 @@ static bool wbinfo_auth_crap(char *username, bool use_ntlmv2, bool use_lanman) if (use_ntlmv2) { DATA_BLOB server_chal; DATA_BLOB names_blob; + const char *netbios_name = NULL; + const char *domain = NULL; + + netbios_name = get_winbind_netbios_name(), + domain = get_winbind_domain(); + if (domain == NULL) { + d_fprintf(stderr, "Failed to get domain from winbindd\n"); + return false; + } server_chal = data_blob(params.password.response.challenge, 8); /* Pretend this is a login to 'us', for blob purposes */ names_blob = NTLMv2_generate_names_blob(NULL, - get_winbind_netbios_name(), - get_winbind_domain()); + netbios_name, + domain); - if (!SMBNTLMv2encrypt(NULL, name_user, name_domain, pass, + if (pass != NULL && + !SMBNTLMv2encrypt(NULL, name_user, name_domain, pass, &server_chal, &names_blob, &lm, &nt, NULL, NULL)) { data_blob_free(&names_blob); data_blob_free(&server_chal); - SAFE_FREE(pass); + TALLOC_FREE(pass); return false; } data_blob_free(&names_blob); @@ -1460,9 +1861,15 @@ static bool wbinfo_auth_crap(char *username, bool use_ntlmv2, bool use_lanman) if (wbc_status == WBC_ERR_AUTH_ERROR) { d_fprintf(stderr, - "error code was %s (0x%x)\nerror messsage was: %s\n", + "wbcAuthenticateUserEx(%s%c%s): error code was " + "%s (0x%x, authoritative=%"PRIu8")\n" + "error message was: %s\n", + name_domain, + winbind_separator(), + name_user, err->nt_string, err->nt_status, + err->authoritative, err->display_string); wbcFreeMemory(err); } else if (WBC_ERROR_IS_OK(wbc_status)) { @@ -1471,6 +1878,161 @@ static bool wbinfo_auth_crap(char *username, bool use_ntlmv2, bool use_lanman) data_blob_free(&nt); data_blob_free(&lm); + + return WBC_ERROR_IS_OK(wbc_status); +} + +/* Authenticate a user with a plaintext password */ + +static bool wbinfo_pam_logon(char *username, bool verbose) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcLogonUserParams params; + struct wbcLogonUserInfo *info = NULL; + struct wbcAuthErrorInfo *error = NULL; + char *s = NULL; + char *p = NULL; + TALLOC_CTX *frame = talloc_tos(); + uint32_t flags; + uint32_t uid; + + ZERO_STRUCT(params); + + if ((s = talloc_strdup(frame, username)) == NULL) { + return false; + } + + if ((p = strchr(s, '%')) != NULL) { + *p = 0; + p++; + params.password = talloc_strdup(frame, p); + } else { + params.password = wbinfo_prompt_pass(frame, NULL, username); + } + params.username = s; + + flags = WBFLAG_PAM_CACHED_LOGIN; + + wbc_status = wbcAddNamedBlob(¶ms.num_blobs, ¶ms.blobs, + "flags", 0, + (uint8_t *)&flags, sizeof(flags)); + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_printf("wbcAddNamedBlob failed: %s\n", + wbcErrorString(wbc_status)); + return false; + } + + uid = getuid(); + + wbc_status = wbcAddNamedBlob(¶ms.num_blobs, ¶ms.blobs, + "user_uid", 0, + (uint8_t *)&uid, sizeof(uid)); + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_printf("wbcAddNamedBlob failed: %s\n", + wbcErrorString(wbc_status)); + return false; + } + + wbc_status = wbcLogonUser(¶ms, &info, &error, NULL); + + if (verbose && (info != NULL)) { + struct wbcAuthUserInfo *i = info->info; + uint32_t j; + + if (i->account_name != NULL) { + d_printf("account_name: %s\n", i->account_name); + } + if (i->user_principal != NULL) { + d_printf("user_principal: %s\n", i->user_principal); + } + if (i->full_name != NULL) { + d_printf("full_name: %s\n", i->full_name); + } + if (i->domain_name != NULL) { + d_printf("domain_name: %s\n", i->domain_name); + } + if (i->dns_domain_name != NULL) { + d_printf("dns_domain_name: %s\n", i->dns_domain_name); + } + if (i->logon_server != NULL) { + d_printf("logon_server: %s\n", i->logon_server); + } + if (i->logon_script != NULL) { + d_printf("logon_script: %s\n", i->logon_script); + } + if (i->profile_path != NULL) { + d_printf("profile_path: %s\n", i->profile_path); + } + if (i->home_directory != NULL) { + d_printf("home_directory: %s\n", i->home_directory); + } + if (i->home_drive != NULL) { + d_printf("home_drive: %s\n", i->home_drive); + } + + d_printf("sids:"); + + for (j=0; jnum_sids; j++) { + char buf[WBC_SID_STRING_BUFLEN]; + wbcSidToStringBuf(&i->sids[j].sid, buf, sizeof(buf)); + d_printf(" %s", buf); + } + d_printf("\n"); + + wbcFreeMemory(info); + info = NULL; + } + + wbcFreeMemory(params.blobs); + + d_printf("plaintext password authentication %s\n", + WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); + + if (!WBC_ERROR_IS_OK(wbc_status) && (error != NULL)) { + d_fprintf(stderr, + "wbcLogonUser(%s): error code was %s (0x%x)\n" + "error message was: %s\n", + params.username, + error->nt_string, + (int)error->nt_status, + error->display_string); + wbcFreeMemory(error); + } + return WBC_ERROR_IS_OK(wbc_status); +} + +/* Save creds with winbind */ + +static bool wbinfo_ccache_save(char *username) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + char *s = NULL; + char *p = NULL; + char *password = NULL; + char *name = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + s = talloc_strdup(frame, username); + if (s == NULL) { + return false; + } + + p = strchr(s, '%'); + if (p != NULL) { + *p = 0; + p++; + password = talloc_strdup(frame, p); + } else { + password = wbinfo_prompt_pass(frame, NULL, username); + } + + name = s; + + wbc_status = wbcCredentialSave(name, password); + + d_printf("saving creds %s\n", + WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); + TALLOC_FREE(frame); return WBC_ERROR_IS_OK(wbc_status); @@ -1500,12 +2062,15 @@ static bool wbinfo_klog(char *username) *p = '%'; } else { fstrcpy(request.data.auth.user, username); - fstrcpy(request.data.auth.pass, getpass("Password: ")); + (void) samba_getpass("Password: ", + request.data.auth.pass, + sizeof(request.data.auth.pass), + false, false); } request.flags |= WBFLAG_PAM_AFS_TOKEN; - result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, + result = winbindd_request_response(NULL, WINBINDD_PAM_AUTH, &request, &response); /* Display response */ @@ -1515,7 +2080,7 @@ static bool wbinfo_klog(char *username) if (response.data.auth.nt_status) d_fprintf(stderr, - "error code was %s (0x%x)\nerror messsage was: %s\n", + "error code was %s (0x%x)\nerror message was: %s\n", response.data.auth.nt_status_string, response.data.auth.nt_status, response.data.auth.error_string); @@ -1555,9 +2120,16 @@ static bool print_domain_users(const char *domain) /* Send request to winbind daemon */ - /* '.' is the special sign for our own domain */ - if (domain && strcmp(domain, ".") == 0) { + if (domain == NULL) { domain = get_winbind_domain(); + } else { + /* '.' is the special sign for our own domain */ + if ((domain[0] == '\0') || strcmp(domain, ".") == 0) { + domain = get_winbind_domain(); + /* '*' is the special sign for all domains */ + } else if (strcmp(domain, "*") == 0) { + domain = NULL; + } } wbc_status = wbcListUsers(domain, &num_users, &users); @@ -1585,13 +2157,22 @@ static bool print_domain_groups(const char *domain) /* Send request to winbind daemon */ - /* '.' is the special sign for our own domain */ - if (domain && strcmp(domain, ".") == 0) { + if (domain == NULL) { domain = get_winbind_domain(); + } else { + /* '.' is the special sign for our own domain */ + if ((domain[0] == '\0') || strcmp(domain, ".") == 0) { + domain = get_winbind_domain(); + /* '*' is the special sign for all domains */ + } else if (strcmp(domain, "*") == 0) { + domain = NULL; + } } wbc_status = wbcListGroups(domain, &num_groups, &groups); if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "failed to call wbcListGroups: %s\n", + wbcErrorString(wbc_status)); return false; } @@ -1650,8 +2231,6 @@ static bool wbinfo_change_user_password(const char *username) d_printf("Password change for user %s %s\n", username, WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); - TALLOC_FREE(frame); - return WBC_ERROR_IS_OK(wbc_status); } @@ -1664,15 +2243,19 @@ enum { OPT_SEQUENCE, OPT_GETDCNAME, OPT_DSGETDCNAME, + OPT_DC_INFO, OPT_USERDOMGROUPS, OPT_SIDALIASES, OPT_USERSIDS, + OPT_LOOKUP_SIDS, OPT_ALLOCATE_UID, OPT_ALLOCATE_GID, OPT_SET_UID_MAPPING, OPT_SET_GID_MAPPING, OPT_REMOVE_UID_MAPPING, OPT_REMOVE_GID_MAPPING, + OPT_SIDS_TO_XIDS, + OPT_XIDS_TO_SIDS, OPT_SEPARATOR, OPT_LIST_ALL_DOMAINS, OPT_LIST_OWN_DOMAIN, @@ -1683,12 +2266,19 @@ enum { OPT_VERBOSE, OPT_ONLINESTATUS, OPT_CHANGE_USER_PASSWORD, + OPT_CCACHE_SAVE, OPT_SID_TO_FULLNAME, + OPT_NTLMV1, OPT_NTLMV2, - OPT_LANMAN + OPT_PAM_LOGON, + OPT_LOGOFF, + OPT_LOGOFF_USER, + OPT_LOGOFF_UID, + OPT_LANMAN, + OPT_KRB5CCNAME }; -int main(int argc, char **argv, char **envp) +int main(int argc, const char **argv, char **envp) { int opt; TALLOC_CTX *frame = talloc_stackframe(); @@ -1700,8 +2290,11 @@ int main(int argc, char **argv, char **envp) int int_subarg = -1; int result = 1; bool verbose = false; - bool use_ntlmv2 = false; + bool use_ntlmv2 = true; bool use_lanman = false; + char *logoff_user = getenv("USER"); + int logoff_uid = geteuid(); + const char *opt_krb5ccname = "FILE"; struct poptOption long_options[] = { POPT_AUTOHELP @@ -1718,6 +2311,9 @@ int main(int argc, char **argv, char **envp) { "sid-to-fullname", 0, POPT_ARG_STRING, &string_arg, OPT_SID_TO_FULLNAME, "Converts sid to fullname", "SID" }, { "lookup-rids", 'R', POPT_ARG_STRING, &string_arg, 'R', "Converts RIDs to names", "RIDs" }, + { "lookup-sids", 0, POPT_ARG_STRING, &string_arg, + OPT_LOOKUP_SIDS, "Converts SIDs to types and names", + "Sid-List"}, { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U', "Converts uid to sid" , "UID" }, { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" }, { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" }, @@ -1730,12 +2326,20 @@ int main(int argc, char **argv, char **envp) { "set-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_GID_MAPPING, "Create or modify gid to sid mapping in idmap", "GID,SID" }, { "remove-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_UID_MAPPING, "Remove uid to sid mapping in idmap", "UID,SID" }, { "remove-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_GID_MAPPING, "Remove gid to sid mapping in idmap", "GID,SID" }, + { "sids-to-unix-ids", 0, POPT_ARG_STRING, &string_arg, + OPT_SIDS_TO_XIDS, "Translate SIDs to Unix IDs", "Sid-List" }, + { "unix-ids-to-sids", 0, POPT_ARG_STRING, &string_arg, + OPT_XIDS_TO_SIDS, "Translate Unix IDs to SIDs", + "ID-List (u g)" }, { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" }, + { "change-secret", 'c', POPT_ARG_NONE, 0, 'c', "Change shared secret" }, + { "ping-dc", 'P', POPT_ARG_NONE, 0, 'P', + "Check the NETLOGON connection" }, { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" }, { "all-domains", 0, POPT_ARG_NONE, 0, OPT_LIST_ALL_DOMAINS, "List all domains (trusted and own domain)" }, { "own-domain", 0, POPT_ARG_NONE, 0, OPT_LIST_OWN_DOMAIN, "List own domain" }, - { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" }, - { "online-status", 0, POPT_ARG_NONE, 0, OPT_ONLINESTATUS, "Show whether domains are marked as online or offline"}, + { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Deprecated command, see --online-status" }, + { "online-status", 0, POPT_ARG_NONE, 0, OPT_ONLINESTATUS, "Show whether domains maintain an active connection"}, { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', "Show most of the info we have about the domain" }, { "user-info", 'i', POPT_ARG_STRING, &string_arg, 'i', "Get user info", "USER" }, { "uid-info", 0, POPT_ARG_INT, &int_arg, OPT_UID_INFO, "Get user info from uid", "UID" }, @@ -1748,10 +2352,23 @@ int main(int argc, char **argv, char **envp) { "sid-aliases", 0, POPT_ARG_STRING, &string_arg, OPT_SIDALIASES, "Get sid aliases", "SID" }, { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" }, { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" }, + { "pam-logon", 0, POPT_ARG_STRING, &string_arg, OPT_PAM_LOGON, + "do a pam logon equivalent", "user%password" }, + { "logoff", 0, POPT_ARG_NONE, NULL, OPT_LOGOFF, + "log off user", "uid" }, + { "logoff-user", 0, POPT_ARG_STRING, &logoff_user, + OPT_LOGOFF_USER, "username to log off" }, + { "logoff-uid", 0, POPT_ARG_INT, &logoff_uid, + OPT_LOGOFF_UID, "uid to log off" }, { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" }, + { "ccache-save", 0, POPT_ARG_STRING, &string_arg, + OPT_CCACHE_SAVE, "Store user and password for ccache " + "operation", "user%password" }, { "getdcname", 0, POPT_ARG_STRING, &string_arg, OPT_GETDCNAME, "Get a DC name for a foreign domain", "domainname" }, { "dsgetdcname", 0, POPT_ARG_STRING, &string_arg, OPT_DSGETDCNAME, "Find a DC for a domain", "domainname" }, + { "dc-info", 0, POPT_ARG_STRING, &string_arg, OPT_DC_INFO, + "Find the currently known DCs", "domainname" }, { "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL }, { "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" }, { "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operation", "domain" }, @@ -1762,10 +2379,13 @@ int main(int argc, char **argv, char **envp) { "krb5auth", 'K', POPT_ARG_STRING, &string_arg, 'K', "authenticate user using Kerberos", "user%password" }, /* destroys wbinfo --help output */ /* "user%password,DOM\\user%password,user@EXAMPLE.COM,EXAMPLE.COM\\user%password" }, */ + { "krb5ccname", 0, POPT_ARG_STRING, &opt_krb5ccname, OPT_KRB5CCNAME, "authenticate user using Kerberos and specific credential cache type", "krb5ccname" }, #endif { "separator", 0, POPT_ARG_NONE, 0, OPT_SEPARATOR, "Get the active winbind separator", NULL }, { "verbose", 0, POPT_ARG_NONE, 0, OPT_VERBOSE, "Print additional information per command", NULL }, { "change-user-password", 0, POPT_ARG_STRING, &string_arg, OPT_CHANGE_USER_PASSWORD, "Change the password for a user", NULL }, + { "ntlmv1", 0, POPT_ARG_NONE, 0, OPT_NTLMV1, + "Use NTLMv1 cryptography for user authentication", NULL}, { "ntlmv2", 0, POPT_ARG_NONE, 0, OPT_NTLMV2, "Use NTLMv2 cryptography for user authentication", NULL}, { "lanman", 0, POPT_ARG_NONE, 0, OPT_LANMAN, "Use lanman cryptography for user authentication", NULL}, POPT_COMMON_VERSION @@ -1773,12 +2393,12 @@ int main(int argc, char **argv, char **envp) }; /* Samba client initialisation */ - load_case_tables(); + smb_init_locale(); /* Parse options */ - pc = poptGetContext("wbinfo", argc, (const char **)argv, + pc = poptGetContext("wbinfo", argc, argv, long_options, 0); /* Parse command line options */ @@ -1794,8 +2414,8 @@ int main(int argc, char **argv, char **envp) case OPT_VERBOSE: verbose = true; break; - case OPT_NTLMV2: - use_ntlmv2 = true; + case OPT_NTLMV1: + use_ntlmv2 = false; break; case OPT_LANMAN: use_lanman = true; @@ -1846,6 +2466,13 @@ int main(int argc, char **argv, char **envp) goto done; } break; + case OPT_LOOKUP_SIDS: + if (!wbinfo_lookup_sids(string_arg)) { + d_fprintf(stderr, "Could not lookup SIDs %s\n", + string_arg); + goto done; + } + break; case 'n': if (!wbinfo_lookupname(string_arg)) { d_fprintf(stderr, "Could not lookup name %s\n", @@ -1955,12 +2582,37 @@ int main(int argc, char **argv, char **envp) goto done; } break; + case OPT_SIDS_TO_XIDS: + if (!wbinfo_sids_to_unix_ids(string_arg)) { + d_fprintf(stderr, "wbinfo_sids_to_unix_ids " + "failed\n"); + goto done; + } + break; + case OPT_XIDS_TO_SIDS: + if (!wbinfo_xids_to_sids(string_arg)) { + d_fprintf(stderr, "wbinfo_xids_to_sids " + "failed\n"); + goto done; + } + break; case 't': - if (!wbinfo_check_secret()) { + if (!wbinfo_check_secret(opt_domain_name)) { d_fprintf(stderr, "Could not check secret\n"); goto done; } break; + case 'c': + if (!wbinfo_change_secret(opt_domain_name)) { + d_fprintf(stderr, "Could not change secret\n"); + goto done; + } + break; + case 'P': + if (!wbinfo_ping_dc(opt_domain_name)) { + goto done; + } + break; case 'm': if (!wbinfo_list_domains(false, verbose)) { d_fprintf(stderr, @@ -2082,6 +2734,23 @@ int main(int argc, char **argv, char **envp) goto done; break; } + case OPT_PAM_LOGON: + if (!wbinfo_pam_logon(string_arg, verbose)) { + d_fprintf(stderr, "pam_logon failed for %s\n", + string_arg); + goto done; + } + break; + case OPT_LOGOFF: + { + wbcErr wbc_status; + + wbc_status = wbcLogoffUser(logoff_user, logoff_uid, + ""); + d_printf("Logoff %s (%d): %s\n", logoff_user, + logoff_uid, wbcErrorString(wbc_status)); + break; + } case 'K': { uint32_t flags = WBFLAG_PAM_KRB5 | WBFLAG_PAM_CACHED_LOGIN | @@ -2089,13 +2758,13 @@ int main(int argc, char **argv, char **envp) WBFLAG_PAM_INFO3_TEXT | WBFLAG_PAM_CONTACT_TRUSTDOM; - if (!wbinfo_auth_krb5(string_arg, "FILE", + if (!wbinfo_auth_krb5(string_arg, opt_krb5ccname, flags)) { d_fprintf(stderr, "Could not authenticate user " "[%s] with Kerberos " "(ccache: %s)\n", string_arg, - "FILE"); + opt_krb5ccname); goto done; } break; @@ -2121,6 +2790,11 @@ int main(int argc, char **argv, char **envp) wbinfo_get_auth_user(); goto done; break; + case OPT_CCACHE_SAVE: + if (!wbinfo_ccache_save(string_arg)) { + goto done; + } + break; case OPT_GETDCNAME: if (!wbinfo_getdcname(string_arg)) { goto done; @@ -2131,6 +2805,11 @@ int main(int argc, char **argv, char **envp) goto done; } break; + case OPT_DC_INFO: + if (!wbinfo_dc_info(string_arg)) { + goto done; + } + break; case OPT_SEPARATOR: { const char sep = winbind_separator(); if ( !sep ) { @@ -2160,12 +2839,12 @@ int main(int argc, char **argv, char **envp) /* generic configuration options */ case OPT_DOMAIN_NAME: - break; case OPT_VERBOSE: - break; case OPT_NTLMV2: - break; case OPT_LANMAN: + case OPT_LOGOFF_USER: + case OPT_LOGOFF_UID: + case OPT_KRB5CCNAME: break; default: d_fprintf(stderr, "Invalid option\n");