X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=source%2Fnsswitch%2Fwbinfo.c;h=2fb46c4a2f701f5cf30cd7824d1ec91989069e79;hp=69d7a1069f9c8bda91a6ae716e4c70b13381f527;hb=7c1f36d84a4c5779ea86923be69e209d0c9c0943;hpb=3c9416c2bedeec7f075e94d45d08f37ae6dd41d1 diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c index 69d7a1069f9..2fb46c4a2f7 100644 --- a/source/nsswitch/wbinfo.c +++ b/source/nsswitch/wbinfo.c @@ -8,7 +8,7 @@ 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 - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,34 +17,45 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -#include "winbindd.h" -#include "debug.h" +#include "winbind_client.h" +#include "libwbclient/wbclient.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -extern int winbindd_fd; +static struct wbcInterfaceDetails *init_interface_details(void) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + static struct wbcInterfaceDetails *details; + + if (details) { + return details; + } + + wbc_status = wbcInterfaceDetails(&details); + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_fprintf(stderr, "could not obtain winbind interface details!\n"); + } + + return details; +} -static char winbind_separator_int(BOOL strict) +static char winbind_separator_int(bool strict) { - struct winbindd_response response; - static BOOL got_sep; + struct wbcInterfaceDetails *details; + static bool got_sep; static char sep; if (got_sep) return sep; - ZERO_STRUCT(response); - - /* Send off request */ + details = init_interface_details(); - if (winbindd_request_response(WINBINDD_INFO, NULL, &response) != - NSS_STATUS_SUCCESS) { + if (!details) { d_fprintf(stderr, "could not obtain winbind separator!\n"); if (strict) { return 0; @@ -53,8 +64,8 @@ static char winbind_separator_int(BOOL strict) return *lp_winbind_separator(); } - sep = response.data.info.winbind_separator; - got_sep = True; + sep = details->winbind_separator; + got_sep = true; if (!sep) { d_fprintf(stderr, "winbind separator was NULL!\n"); @@ -70,346 +81,429 @@ static char winbind_separator_int(BOOL strict) static char winbind_separator(void) { - return winbind_separator_int(False); + return winbind_separator_int(false); } static const char *get_winbind_domain(void) { - struct winbindd_response response; - static fstring winbind_domain; + static struct wbcInterfaceDetails *details; - ZERO_STRUCT(response); - - /* Send off request */ + details = init_interface_details(); - if (winbindd_request_response(WINBINDD_DOMAIN_NAME, NULL, &response) != - NSS_STATUS_SUCCESS) { + if (!details) { d_fprintf(stderr, "could not obtain winbind domain name!\n"); - - /* HACK: (this module should not call lp_ funtions) */ + + /* HACK: (this module should not call lp_ functions) */ return lp_workgroup(); } - fstrcpy(winbind_domain, response.data.domain_name); - - return winbind_domain; - + return details->netbios_domain; } /* Copy of parse_domain_user from winbindd_util.c. Parse a string of the form DOMAIN/user into a domain and a user */ -static BOOL parse_wbinfo_domain_user(const char *domuser, fstring domain, +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; + return true; } - + fstrcpy(user, p+1); fstrcpy(domain, domuser); domain[PTR_DIFF(p, domuser)] = 0; strupper_m(domain); - return True; + return true; } /* pull pwent info for a given user */ -static BOOL wbinfo_get_userinfo(char *user) +static bool wbinfo_get_userinfo(char *user) { - struct winbindd_request request; - struct winbindd_response response; - NSS_STATUS result; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct passwd *pwd = NULL; - /* Send request */ - - fstrcpy(request.data.username, user); + wbc_status = wbcGetpwnam(user, &pwd); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - result = winbindd_request_response(WINBINDD_GETPWNAM, &request, &response); - - if (result != NSS_STATUS_SUCCESS) - return False; - - d_printf( "%s:%s:%d:%d:%s:%s:%s\n", - response.data.pw.pw_name, - response.data.pw.pw_passwd, - response.data.pw.pw_uid, - response.data.pw.pw_gid, - response.data.pw.pw_gecos, - response.data.pw.pw_dir, - response.data.pw.pw_shell ); - - return True; + d_printf("%s:%s:%d:%d:%s:%s:%s\n", + pwd->pw_name, + pwd->pw_passwd, + pwd->pw_uid, + pwd->pw_gid, + pwd->pw_gecos, + pwd->pw_dir, + pwd->pw_shell); + + return true; } -/* List groups a user is a member of */ +/* pull pwent info for a given uid */ +static bool wbinfo_get_uidinfo(int uid) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct passwd *pwd = NULL; + + wbc_status = wbcGetpwuid(uid, &pwd); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } -static BOOL wbinfo_get_usergroups(char *user) + d_printf("%s:%s:%d:%d:%s:%s:%s\n", + pwd->pw_name, + pwd->pw_passwd, + pwd->pw_uid, + pwd->pw_gid, + pwd->pw_gecos, + pwd->pw_dir, + pwd->pw_shell); + + return true; +} + +/* pull grent for a given group */ +static bool wbinfo_get_groupinfo(const char *group) { - struct winbindd_request request; - struct winbindd_response response; - NSS_STATUS result; - int i; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct group *grp; - /* Send request */ + wbc_status = wbcGetgrnam(group, &grp); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - fstrcpy(request.data.username, user); + d_printf("%s:%s:%d\n", + grp->gr_name, + grp->gr_passwd, + grp->gr_gid); - result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); + wbcFreeMemory(grp); - if (result != NSS_STATUS_SUCCESS) - return False; + return true; +} + +/* List groups a user is a member of */ + +static bool wbinfo_get_usergroups(const char *user) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + uint32_t num_groups; + uint32_t i; + gid_t *groups = NULL; - for (i = 0; i < response.data.num_entries; i++) - d_printf("%d\n", (int)((gid_t *)response.extra_data.data)[i]); + /* Send request */ + + wbc_status = wbcGetGroups(user, &num_groups, &groups); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - SAFE_FREE(response.extra_data.data); + for (i = 0; i < num_groups; i++) { + d_printf("%d\n", (int)groups[i]); + } + + wbcFreeMemory(groups); - return True; + return true; } /* List group SIDs a user SID is a member of */ -static BOOL wbinfo_get_usersids(char *user_sid) +static bool wbinfo_get_usersids(const char *user_sid_str) { - struct winbindd_request request; - struct winbindd_response response; - NSS_STATUS result; - int i; - const char *s; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + uint32_t num_sids; + uint32_t i; + struct wbcDomainSid user_sid, *sids = NULL; /* Send request */ - fstrcpy(request.data.sid, user_sid); - result = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response); + wbc_status = wbcStringToSid(user_sid_str, &user_sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - if (result != NSS_STATUS_SUCCESS) - return False; + wbc_status = wbcLookupUserSids(&user_sid, false, &num_sids, &sids); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - s = response.extra_data.data; - for (i = 0; i < response.data.num_entries; i++) { - d_printf("%s\n", s); - s += strlen(s) + 1; + 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; + } + d_printf("%s\n", str); + wbcFreeMemory(str); } - SAFE_FREE(response.extra_data.data); + wbcFreeMemory(sids); - return True; + return true; } -static BOOL wbinfo_get_userdomgroups(const char *user_sid) +static bool wbinfo_get_userdomgroups(const char *user_sid_str) { - struct winbindd_request request; - struct winbindd_response response; - NSS_STATUS result; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + uint32_t num_sids; + uint32_t i; + struct wbcDomainSid user_sid, *sids = NULL; /* Send request */ - fstrcpy(request.data.sid, user_sid); - result = winbindd_request_response(WINBINDD_GETUSERDOMGROUPS, &request, - &response); + wbc_status = wbcStringToSid(user_sid_str, &user_sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - if (result != NSS_STATUS_SUCCESS) - return False; + wbc_status = wbcLookupUserSids(&user_sid, true, &num_sids, &sids); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - if (response.data.num_entries != 0) - printf("%s", (char *)response.extra_data.data); - - SAFE_FREE(response.extra_data.data); + 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; + } + d_printf("%s\n", str); + wbcFreeMemory(str); + } + + wbcFreeMemory(sids); - return True; + return true; } /* Convert NetBIOS name to IP */ -static BOOL wbinfo_wins_byname(char *name) +static bool wbinfo_wins_byname(const char *name) { - struct winbindd_request request; - struct winbindd_response response; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); - - /* Send request */ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + char *ip = NULL; - fstrcpy(request.data.winsreq, name); - - if (winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response) != - NSS_STATUS_SUCCESS) { - return False; + wbc_status = wbcResolveWinsByName(name, &ip); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; } /* Display response */ - d_printf("%s\n", response.data.winsresp); + d_printf("%s\n", ip); - return True; + wbcFreeMemory(ip); + + return true; } /* Convert IP to NetBIOS name */ -static BOOL wbinfo_wins_byip(char *ip) +static bool wbinfo_wins_byip(const char *ip) { - struct winbindd_request request; - struct winbindd_response response; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + char *name = NULL; - ZERO_STRUCT(request); - ZERO_STRUCT(response); - - /* Send request */ - - fstrcpy(request.data.winsreq, ip); - - if (winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response) != - NSS_STATUS_SUCCESS) { - return False; + wbc_status = wbcResolveWinsByIP(ip, &name); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; } /* Display response */ - d_printf("%s\n", response.data.winsresp); + d_printf("%s\n", name); + + wbcFreeMemory(name); - return True; + return true; } -/* List trusted domains */ +/* List all/trusted domains */ -static BOOL wbinfo_list_domains(BOOL list_all_domains) +static bool wbinfo_list_domains(bool list_all_domains, bool verbose) { - struct winbindd_request request; - struct winbindd_response response; + struct wbcDomainInfo *domain_list = NULL; + size_t num_domains; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + bool print_all = !list_all_domains && verbose; + int i; - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbc_status = wbcListTrusts(&domain_list, &num_domains); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - /* Send request */ + if (print_all) { + d_printf("%-16s%-24s%-12s%-12s%-5s%-5s\n", + "Domain Name", "DNS Domain", "Trust Type", + "Transitive", "In", "Out"); + } - request.data.list_all_domains = list_all_domains; + for (i=0; isid, &sid_str); + if (!WBC_ERROR_IS_OK(wbc_status)) { + wbcFreeMemory(dinfo); + return false; + } /* Display response */ - d_printf("Name : %s\n", response.data.domain_info.name); - d_printf("Alt_Name : %s\n", response.data.domain_info.alt_name); + d_printf("Name : %s\n", dinfo->short_name); + d_printf("Alt_Name : %s\n", dinfo->dns_name); - d_printf("SID : %s\n", response.data.domain_info.sid); + d_printf("SID : %s\n", sid_str); d_printf("Active Directory : %s\n", - response.data.domain_info.active_directory ? "Yes" : "No"); + (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_AD) ? "Yes" : "No"); d_printf("Native : %s\n", - response.data.domain_info.native_mode ? "Yes" : "No"); + (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_NATIVE) ? "Yes" : "No"); d_printf("Primary : %s\n", - response.data.domain_info.primary ? "Yes" : "No"); + (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_PRIMARY) ? "Yes" : "No"); - d_printf("Sequence : %d\n", response.data.domain_info.sequence_number); + wbcFreeMemory(sid_str); + wbcFreeMemory(dinfo); - return True; + return true; } /* Get a foreign DC's name */ -static BOOL wbinfo_getdcname(const char *domain_name) +static bool wbinfo_getdcname(const char *domain_name) { struct winbindd_request request; struct winbindd_response response; @@ -424,216 +518,369 @@ static BOOL wbinfo_getdcname(const char *domain_name) if (winbindd_request_response(WINBINDD_GETDCNAME, &request, &response) != NSS_STATUS_SUCCESS) { d_fprintf(stderr, "Could not get dc name for %s\n", domain_name); - return False; + return false; + } + + /* Display response */ + + d_printf("%s\n", response.data.dc_name); + + return true; +} + +/* Find a DC */ +static bool wbinfo_dsgetdcname(const char *domain_name, uint32_t flags) +{ + struct winbindd_request request; + struct winbindd_response response; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + fstrcpy(request.domain_name, domain_name); + request.flags = flags; + + request.flags |= DS_DIRECTORY_SERVICE_REQUIRED; + + /* Send request */ + + if (winbindd_request_response(WINBINDD_DSGETDCNAME, &request, &response) != + NSS_STATUS_SUCCESS) { + d_fprintf(stderr, "Could not find dc for %s\n", domain_name); + return false; } /* Display response */ d_printf("%s\n", response.data.dc_name); - return True; + return true; } /* Check trust account password */ -static BOOL wbinfo_check_secret(void) +static bool wbinfo_check_secret(void) { - struct winbindd_response response; - NSS_STATUS result; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcAuthErrorInfo *error = NULL; - ZERO_STRUCT(response); + wbc_status = wbcCheckTrustCredentials(NULL, &error); - result = winbindd_request_response(WINBINDD_CHECK_MACHACC, NULL, &response); - - d_printf("checking the trust secret via RPC calls %s\n", - (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); + d_printf("checking the trust secret via RPC calls %s\n", + WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); - if (result != NSS_STATUS_SUCCESS) - d_fprintf(stderr, "error code was %s (0x%x)\n", - response.data.auth.nt_status_string, - response.data.auth.nt_status); - - return result == NSS_STATUS_SUCCESS; + if (wbc_status == WBC_ERR_AUTH_ERROR) { + d_fprintf(stderr, "error code was %s (0x%x)\n", + error->nt_string, error->nt_status); + wbcFreeMemory(error); + } + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + return true; } /* Convert uid to sid */ -static BOOL wbinfo_uid_to_sid(uid_t uid) +static bool wbinfo_uid_to_sid(uid_t uid) { - struct winbindd_request request; - struct winbindd_response response; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainSid sid; + char *sid_str = NULL; /* Send request */ - request.data.uid = uid; + wbc_status = wbcUidToSid(uid, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response) != - NSS_STATUS_SUCCESS) - return False; + wbc_status = wbcSidToString(&sid, &sid_str); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } /* Display response */ - d_printf("%s\n", response.data.sid.sid); + d_printf("%s\n", sid_str); - return True; + wbcFreeMemory(sid_str); + + return true; } /* Convert gid to sid */ -static BOOL wbinfo_gid_to_sid(gid_t gid) +static bool wbinfo_gid_to_sid(gid_t gid) { - struct winbindd_request request; - struct winbindd_response response; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainSid sid; + char *sid_str = NULL; /* Send request */ - request.data.gid = gid; + wbc_status = wbcGidToSid(gid, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - if (winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response) != - NSS_STATUS_SUCCESS) - return False; + wbc_status = wbcSidToString(&sid, &sid_str); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } /* Display response */ - d_printf("%s\n", response.data.sid.sid); + d_printf("%s\n", sid_str); + + wbcFreeMemory(sid_str); - return True; + return true; } /* Convert sid to uid */ -static BOOL wbinfo_sid_to_uid(char *sid) +static bool wbinfo_sid_to_uid(const char *sid_str) { - struct winbindd_request request; - struct winbindd_response response; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainSid sid; + uid_t uid; /* Send request */ - fstrcpy(request.data.sid, sid); + wbc_status = wbcStringToSid(sid_str, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - if (winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response) != - NSS_STATUS_SUCCESS) - return False; + wbc_status = wbcSidToUid(&sid, &uid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } /* Display response */ - d_printf("%d\n", (int)response.data.uid); + d_printf("%d\n", (int)uid); - return True; + return true; } -static BOOL wbinfo_sid_to_gid(char *sid) +static bool wbinfo_sid_to_gid(const char *sid_str) { - struct winbindd_request request; - struct winbindd_response response; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainSid sid; + gid_t gid; /* Send request */ - fstrcpy(request.data.sid, sid); + wbc_status = wbcStringToSid(sid_str, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - if (winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response) != - NSS_STATUS_SUCCESS) - return False; + wbc_status = wbcSidToGid(&sid, &gid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } /* Display response */ - d_printf("%d\n", (int)response.data.gid); + d_printf("%d\n", (int)gid); - return True; + return true; } -static BOOL wbinfo_allocate_uid(void) +static bool wbinfo_allocate_uid(void) { + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; uid_t uid; - if (!winbind_allocate_uid(&uid)) - return False; + /* Send request */ + + wbc_status = wbcAllocateUid(&uid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + /* Display response */ d_printf("New uid: %d\n", uid); - return True; + return true; } -static BOOL wbinfo_allocate_gid(void) +static bool wbinfo_allocate_gid(void) { + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; gid_t gid; - if (!winbind_allocate_gid(&gid)) - return False; + /* Send request */ + + wbc_status = wbcAllocateGid(&gid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + /* Display response */ d_printf("New gid: %d\n", gid); - return True; + return true; } /* Convert sid to string */ -static BOOL wbinfo_lookupsid(char *sid) +static bool wbinfo_lookupsid(const char *sid_str) { - struct winbindd_request request; - struct winbindd_response response; - - ZERO_STRUCT(request); - ZERO_STRUCT(response); + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainSid sid; + char *domain; + char *name; + enum wbcSidType type; /* Send off request */ - fstrcpy(request.data.sid, sid); + wbc_status = wbcStringToSid(sid_str, &sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - if (winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response) != - NSS_STATUS_SUCCESS) - 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", response.data.name.dom_name, - winbind_separator(), response.data.name.name, - response.data.name.type); + d_printf("%s%c%s %d\n", + domain, winbind_separator(), name, type); - return True; + return true; +} + +/* Lookup a list of RIDs */ + +static bool wbinfo_lookuprids(const char *domain, const char *arg) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainInfo *dinfo = NULL; + char *domain_name = NULL; + const char **names = NULL; + enum wbcSidType *types = NULL; + size_t i; + int num_rids; + uint32 *rids = NULL; + const char *p; + char *ridstr; + TALLOC_CTX *mem_ctx = NULL; + bool ret = false; + + if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')) { + domain = get_winbind_domain(); + } + + /* Send request */ + + wbc_status = wbcDomainInfo(domain, &dinfo); + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_printf("wbcDomainInfo(%s) failed: %s\n", domain, + wbcErrorString(wbc_status)); + goto done; + } + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + d_printf("talloc_new failed\n"); + goto done; + } + + num_rids = 0; + rids = NULL; + p = arg; + + while (next_token_talloc(mem_ctx, &p, &ridstr, " ,\n")) { + uint32 rid = strtoul(ridstr, NULL, 10); + ADD_TO_ARRAY(mem_ctx, uint32, rid, &rids, &num_rids); + } + + if (rids == NULL) { + d_printf("no rids\n"); + goto done; + } + + wbc_status = wbcLookupRids(&dinfo->sid, num_rids, rids, + (const char **)&domain_name, &names, &types); + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_printf("winbind_lookup_rids failed: %s\n", + wbcErrorString(wbc_status)); + goto done; + } + + d_printf("Domain: %s\n", domain_name); + + for (i=0; int_string, + err->nt_status, + err->display_string); + wbcFreeMemory(err); + } else if (WBC_ERROR_IS_OK(wbc_status)) { + wbcFreeMemory(info); + } + + data_blob_free(&nt); + data_blob_free(&lm); - return result == NSS_STATUS_SUCCESS; + return WBC_ERROR_IS_OK(wbc_status); } /* Authenticate a user with a plaintext password and set a token */ -static BOOL wbinfo_klog(char *username) +static bool wbinfo_klog(char *username) { struct winbindd_request request; struct winbindd_response response; - NSS_STATUS result; - char *p; + NSS_STATUS result; + char *p; /* Send off request */ ZERO_STRUCT(request); ZERO_STRUCT(response); - p = strchr(username, '%'); + p = strchr(username, '%'); - if (p) { - *p = 0; - fstrcpy(request.data.auth.user, username); - fstrcpy(request.data.auth.pass, p + 1); - *p = '%'; - } else { - fstrcpy(request.data.auth.user, username); + if (p) { + *p = 0; + fstrcpy(request.data.auth.user, username); + fstrcpy(request.data.auth.pass, p + 1); + *p = '%'; + } else { + fstrcpy(request.data.auth.user, username); fstrcpy(request.data.auth.pass, getpass("Password: ")); } @@ -864,114 +1128,95 @@ static BOOL wbinfo_klog(char *username) /* Display response */ - d_printf("plaintext password authentication %s\n", - (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); + d_printf("plaintext password authentication %s\n", + (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); if (response.data.auth.nt_status) d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n", - response.data.auth.nt_status_string, + response.data.auth.nt_status_string, response.data.auth.nt_status, response.data.auth.error_string); if (result != NSS_STATUS_SUCCESS) - return False; + return false; if (response.extra_data.data == NULL) { d_fprintf(stderr, "Did not get token data\n"); - return False; + return false; } if (!afs_settoken_str((char *)response.extra_data.data)) { d_fprintf(stderr, "Could not set token\n"); - return False; + return false; } d_printf("Successfully created AFS token\n"); - return True; + return true; } /* Print domain users */ -static BOOL print_domain_users(const char *domain) +static bool print_domain_users(const char *domain) { - struct winbindd_request request; - struct winbindd_response response; - const char *extra_data; - fstring name; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + uint32_t i; + uint32_t num_users = 0; + const char **users = NULL; /* Send request to winbind daemon */ - ZERO_STRUCT(request); - ZERO_STRUCT(response); - - if (domain) { - /* '.' is the special sign for our own domwin */ - if ( strequal(domain, ".") ) - fstrcpy( request.domain_name, lp_workgroup() ); - else - fstrcpy( request.domain_name, domain ); + /* '.' is the special sign for our own domain */ + if (domain && strcmp(domain, ".") == 0) { + domain = get_winbind_domain(); } - if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) != - NSS_STATUS_SUCCESS) - return False; - - /* Look through extra data */ - - if (!response.extra_data.data) - return False; + wbc_status = wbcListUsers(domain, &num_users, &users); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - extra_data = (const char *)response.extra_data.data; + for (i=0; i < num_users; i++) { + d_printf("%s\n", users[i]); + } - while(next_token(&extra_data, name, ",", sizeof(fstring))) - d_printf("%s\n", name); - - SAFE_FREE(response.extra_data.data); + wbcFreeMemory(users); - return True; + return true; } /* Print domain groups */ -static BOOL print_domain_groups(const char *domain) +static bool print_domain_groups(const char *domain) { - struct winbindd_request request; - struct winbindd_response response; - const char *extra_data; - fstring name; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + uint32_t i; + uint32_t num_groups = 0; + const char **groups = NULL; - ZERO_STRUCT(request); - ZERO_STRUCT(response); + /* Send request to winbind daemon */ - if (domain) { - if ( strequal(domain, ".") ) - fstrcpy( request.domain_name, lp_workgroup() ); - else - fstrcpy( request.domain_name, domain ); + /* '.' is the special sign for our own domain */ + if (domain && strcmp(domain, ".") == 0) { + domain = get_winbind_domain(); } - if (winbindd_request_response(WINBINDD_LIST_GROUPS, &request, &response) != - NSS_STATUS_SUCCESS) - return False; - - /* Look through extra data */ - - if (!response.extra_data.data) - return False; + wbc_status = wbcListGroups(domain, &num_groups, &groups); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } - extra_data = (const char *)response.extra_data.data; + for (i=0; i < num_groups; i++) { + d_printf("%s\n", groups[i]); + } - while(next_token(&extra_data, name, ",", sizeof(fstring))) - d_printf("%s\n", name); + wbcFreeMemory(groups); - SAFE_FREE(response.extra_data.data); - - return True; + return true; } /* Set the authorised user for winbindd access in secrets.tdb */ -static BOOL wbinfo_set_auth_user(char *username) +static bool wbinfo_set_auth_user(char *username) { const char *password; char *p; @@ -989,7 +1234,7 @@ static BOOL wbinfo_set_auth_user(char *username) } else { char *thepass = getpass("Password: "); if (thepass) { - password = thepass; + password = thepass; } else password = ""; } @@ -1003,7 +1248,7 @@ static BOOL wbinfo_set_auth_user(char *username) if (!secrets_store(SECRETS_AUTH_USER, user, strlen(user) + 1)) { d_fprintf(stderr, "error storing username\n"); - return False; + return false; } /* We always have a domain name added by the @@ -1012,7 +1257,7 @@ static BOOL wbinfo_set_auth_user(char *username) if (!secrets_store(SECRETS_AUTH_DOMAIN, domain, strlen(domain) + 1)) { d_fprintf(stderr, "error storing domain name\n"); - return False; + return false; } } else { @@ -1025,13 +1270,13 @@ static BOOL wbinfo_set_auth_user(char *username) if (!secrets_store(SECRETS_AUTH_PASSWORD, password, strlen(password) + 1)) { d_fprintf(stderr, "error storing password\n"); - return False; + return false; } } else secrets_delete(SECRETS_AUTH_PASSWORD); - return True; + return true; } static void wbinfo_get_auth_user(void) @@ -1039,7 +1284,7 @@ static void wbinfo_get_auth_user(void) char *user, *domain, *password; /* Lift data from secrets file */ - + secrets_fetch_ipc_userpass(&user, &domain, &password); if ((!user || !*user) && (!domain || !*domain ) && (!password || !*password)){ @@ -1061,18 +1306,18 @@ static void wbinfo_get_auth_user(void) SAFE_FREE(password); } -static BOOL wbinfo_ping(void) +static bool wbinfo_ping(void) { - NSS_STATUS result; + wbcErr wbc_status; - result = winbindd_request_response(WINBINDD_PING, NULL, NULL); + wbc_status = wbcPing(); /* Display response */ - d_printf("Ping to winbindd %s on fd %d\n", - (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", winbindd_fd); + d_printf("Ping to winbindd %s\n", + WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); - return result == NSS_STATUS_SUCCESS; + return WBC_ERROR_IS_OK(wbc_status); } /* Main program */ @@ -1083,29 +1328,35 @@ enum { OPT_DOMAIN_NAME, OPT_SEQUENCE, OPT_GETDCNAME, + OPT_DSGETDCNAME, OPT_USERDOMGROUPS, OPT_USERSIDS, OPT_ALLOCATE_UID, OPT_ALLOCATE_GID, OPT_SEPARATOR, OPT_LIST_ALL_DOMAINS, - OPT_LIST_OWN_DOMAIN + OPT_LIST_OWN_DOMAIN, + OPT_UID_INFO, + OPT_GROUP_INFO, + OPT_VERBOSE, + OPT_ONLINESTATUS }; -int main(int argc, char **argv) +int main(int argc, char **argv, char **envp) { int opt; - + TALLOC_CTX *frame = talloc_stackframe(); poptContext pc; static char *string_arg; static char *opt_domain_name; static int int_arg; int result = 1; + bool verbose = false; struct poptOption long_options[] = { POPT_AUTOHELP - /* longName, shortName, argInfo, argPtr, value, descrip, + /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users", "domain"}, @@ -1114,6 +1365,7 @@ int main(int argc, char **argv) { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I', "Converts IP address to NetBIOS name", "IP" }, { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n', "Converts name to sid", "NAME" }, { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's', "Converts sid to name", "SID" }, + { "lookup-rids", 'R', POPT_ARG_STRING, &string_arg, 'R', "Converts RIDs to names", "RIDs" }, { "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" }, @@ -1127,8 +1379,11 @@ int main(int argc, char **argv) { "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"}, { "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" }, + { "group-info", 0, POPT_ARG_STRING, &string_arg, OPT_GROUP_INFO, "Get group info", "GROUP" }, { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" }, { "user-domgroups", 0, POPT_ARG_STRING, &string_arg, OPT_USERDOMGROUPS, "Get user domain groups", "SID" }, @@ -1137,6 +1392,7 @@ int main(int argc, char **argv) { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "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" }, { "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" }, @@ -1149,6 +1405,8 @@ int main(int argc, char **argv) /* "user%password,DOM\\user%password,user@EXAMPLE.COM,EXAMPLE.COM\\user%password" }, */ #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 }, + POPT_COMMON_CONFIGFILE POPT_COMMON_VERSION POPT_TABLEEND }; @@ -1156,16 +1414,6 @@ int main(int argc, char **argv) /* Samba client initialisation */ load_case_tables(); - if (!lp_load(dyn_CONFIGFILE, True, False, False, True)) { - d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n", - dyn_CONFIGFILE, strerror(errno)); - exit(1); - } - - if (!init_names()) - return 1; - - load_interfaces(); /* Parse options */ @@ -1180,10 +1428,26 @@ int main(int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { /* get the generic configuration parameters like --domain */ + switch (opt) { + case OPT_VERBOSE: + verbose = True; + break; + } } poptFreeContext(pc); + if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, true)) { + d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n", + get_dyn_CONFIGFILE(), strerror(errno)); + exit(1); + } + + if (!init_names()) + return 1; + + load_interfaces(); + pc = poptGetContext(NULL, argc, (const char **)argv, long_options, POPT_CONTEXT_KEEP_FIRST); @@ -1207,6 +1471,12 @@ int main(int argc, char **argv) goto done; } break; + case 'R': + if (!wbinfo_lookuprids(opt_domain_name, string_arg)) { + d_fprintf(stderr, "Could not lookup RIDs %s\n", string_arg); + goto done; + } + break; case 'n': if (!wbinfo_lookupname(string_arg)) { d_fprintf(stderr, "Could not lookup name %s\n", string_arg); @@ -1271,7 +1541,7 @@ int main(int argc, char **argv) } break; case 'm': - if (!wbinfo_list_domains(False)) { + if (!wbinfo_list_domains(false, verbose)) { d_fprintf(stderr, "Could not list trusted domains\n"); goto done; } @@ -1282,6 +1552,12 @@ int main(int argc, char **argv) goto done; } break; + case OPT_ONLINESTATUS: + if (!wbinfo_show_onlinestatus(opt_domain_name)) { + d_fprintf(stderr, "Could not show online-status\n"); + goto done; + } + break; case 'D': if (!wbinfo_domain_info(string_arg)) { d_fprintf(stderr, "Could not get domain info\n"); @@ -1295,6 +1571,20 @@ int main(int argc, char **argv) goto done; } break; + case OPT_UID_INFO: + if ( !wbinfo_get_uidinfo(int_arg)) { + d_fprintf(stderr, "Could not get info for uid " + "%d\n", int_arg); + goto done; + } + break; + case OPT_GROUP_INFO: + if ( !wbinfo_get_groupinfo(string_arg)) { + d_fprintf(stderr, "Could not get info for " + "group %s\n", string_arg); + goto done; + } + break; case 'r': if (!wbinfo_get_usergroups(string_arg)) { d_fprintf(stderr, "Could not get groups for user %s\n", @@ -1317,18 +1607,18 @@ int main(int argc, char **argv) } break; case 'a': { - BOOL got_error = False; + bool got_error = false; if (!wbinfo_auth(string_arg)) { d_fprintf(stderr, "Could not authenticate user %s with " "plaintext password\n", string_arg); - got_error = True; + got_error = true; } if (!wbinfo_auth_crap(string_arg)) { d_fprintf(stderr, "Could not authenticate user %s with " "challenge/response\n", string_arg); - got_error = True; + got_error = true; } if (got_error) @@ -1336,37 +1626,16 @@ int main(int argc, char **argv) break; } case 'K': { - BOOL got_error = False; uint32 flags = WBFLAG_PAM_KRB5 | WBFLAG_PAM_CACHED_LOGIN | WBFLAG_PAM_FALLBACK_AFTER_KRB5 | WBFLAG_PAM_INFO3_TEXT; - fstring tok; - int i; - const char *arg[] = { NULL, NULL }; - const char *cctypes[] = { "FILE", - "KCM", - "KCM:0", - "Garbage", - NULL, - "0"}; - - arg[0] = string_arg; - - while (next_token(arg, tok, LIST_SEP, sizeof(tok))) { - - for (i=0; i < ARRAY_SIZE(cctypes); i++) { - if (!wbinfo_auth_krb5(tok, cctypes[i], flags)) { - d_fprintf(stderr, "Could not authenticate user [%s] with " - "Kerberos (ccache: %s)\n", tok, cctypes[i]); - got_error = True; - } - } - } - if (got_error) + if (!wbinfo_auth_krb5(string_arg, "FILE", flags)) { + d_fprintf(stderr, "Could not authenticate user [%s] with " + "Kerberos (ccache: %s)\n", string_arg, "FILE"); goto done; - + } break; } case 'k': @@ -1394,8 +1663,13 @@ int main(int argc, char **argv) goto done; } break; + case OPT_DSGETDCNAME: + if (!wbinfo_dsgetdcname(string_arg, 0)) { + goto done; + } + break; case OPT_SEPARATOR: { - const char sep = winbind_separator_int(True); + const char sep = winbind_separator_int(true); if ( !sep ) { goto done; } @@ -1403,7 +1677,7 @@ int main(int argc, char **argv) break; } case OPT_LIST_ALL_DOMAINS: - if (!wbinfo_list_domains(True)) { + if (!wbinfo_list_domains(true, verbose)) { goto done; } break; @@ -1415,6 +1689,8 @@ int main(int argc, char **argv) /* generic configuration options */ case OPT_DOMAIN_NAME: break; + case OPT_VERBOSE: + break; default: d_fprintf(stderr, "Invalid option\n"); poptPrintHelp(pc, stderr, 0); @@ -1427,6 +1703,8 @@ int main(int argc, char **argv) /* Exit code */ done: + talloc_destroy(frame); + poptFreeContext(pc); return result; }