DIsplay the short domain name in "wbinfo -m " by default.
[ira/wip.git] / source / nsswitch / wbinfo.c
index 6db37fca80fcf528bea7580f0b4090a85d9ff78d..d62e82a659c989377f7fa95dc7bffaf866fa6f41 100644 (file)
@@ -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,
    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 <http://www.gnu.org/licenses/>.
 */
 
 #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 char winbind_separator_int(BOOL strict)
+static char winbind_separator_int(bool strict)
 {
        struct winbindd_response response;
-       static BOOL got_sep;
+       static bool got_sep;
        static char sep;
 
        if (got_sep)
@@ -54,7 +51,7 @@ static char winbind_separator_int(BOOL strict)
        }
 
        sep = response.data.info.winbind_separator;
-       got_sep = True;
+       got_sep = true;
 
        if (!sep) {
                d_fprintf(stderr, "winbind separator was NULL!\n");
@@ -70,124 +67,140 @@ 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;
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct wbcDomainInfo *dinfo = NULL;
        static fstring winbind_domain;
 
-       ZERO_STRUCT(response);
+       ZERO_STRUCT(dinfo);
 
-       /* Send off request */
+       wbc_status = wbcDomainInfo(".", &dinfo);
 
-       if (winbindd_request_response(WINBINDD_DOMAIN_NAME, NULL, &response) !=
-           NSS_STATUS_SUCCESS) {
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
                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);
+       fstrcpy(winbind_domain, dinfo->short_name);
 
-       return winbind_domain;
+       wbcFreeMemory(dinfo);
 
+       return winbind_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;
 }
 
-/* pull grent for a given group */
-static BOOL wbinfo_get_groupinfo(char *group)
+/* pull pwent info for a given uid */
+static bool wbinfo_get_uidinfo(int uid)
 {
-       struct winbindd_request request;
-       struct winbindd_response response;
-       NSS_STATUS result;
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct passwd *pwd = NULL;
 
-       ZERO_STRUCT(request);
-       ZERO_STRUCT(response);
+       wbc_status = wbcGetpwuid(uid, &pwd);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               return false;
+       }
 
-       /* Send request */
+       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;
+}
 
-       fstrcpy(request.data.groupname, group);
+/* pull grent for a given group */
+static bool wbinfo_get_groupinfo(const char *group)
+{
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct group *grp;
 
-       result = winbindd_request_response(WINBINDD_GETGRNAM, &request,
-                                          &response);
+       wbc_status = wbcGetgrnam(group, &grp);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               return false;
+       }
 
-       if ( result != NSS_STATUS_SUCCESS)
-               return False;
+       d_printf("%s:%s:%d\n",
+                grp->gr_name,
+                grp->gr_passwd,
+                grp->gr_gid);
 
-       d_printf( "%s:%s:%d\n",
-                 response.data.gr.gr_name,
-                 response.data.gr.gr_passwd,
-                 response.data.gr.gr_gid );
-       
-       return True;
+       wbcFreeMemory(grp);
+
+       return true;
 }
 
 /* List groups a user is a member of */
 
-static BOOL wbinfo_get_usergroups(char *user)
+static bool wbinfo_get_usergroups(char *user)
 {
        struct winbindd_request request;
        struct winbindd_response response;
        NSS_STATUS result;
        int i;
-       
+
        ZERO_STRUCT(request);
        ZERO_STRUCT(response);
 
@@ -198,77 +211,91 @@ static BOOL wbinfo_get_usergroups(char *user)
        result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
 
        if (result != NSS_STATUS_SUCCESS)
-               return False;
+               return false;
 
        for (i = 0; i < response.data.num_entries; i++)
                d_printf("%d\n", (int)((gid_t *)response.extra_data.data)[i]);
 
        SAFE_FREE(response.extra_data.data);
 
-       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 = (const char *)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);
+       }
 
-       return True;
+       wbcFreeMemory(sids);
+
+       return true;
 }
 
 /* Convert NetBIOS name to IP */
 
-static BOOL wbinfo_wins_byname(char *name)
+static bool wbinfo_wins_byname(char *name)
 {
        struct winbindd_request request;
        struct winbindd_response response;
@@ -282,19 +309,19 @@ static BOOL wbinfo_wins_byname(char *name)
 
        if (winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response) !=
            NSS_STATUS_SUCCESS) {
-               return False;
+               return false;
        }
 
        /* Display response */
 
        d_printf("%s\n", response.data.winsresp);
 
-       return True;
+       return true;
 }
 
 /* Convert IP to NetBIOS name */
 
-static BOOL wbinfo_wins_byip(char *ip)
+static bool wbinfo_wins_byip(char *ip)
 {
        struct winbindd_request request;
        struct winbindd_response response;
@@ -308,23 +335,25 @@ static BOOL wbinfo_wins_byip(char *ip)
 
        if (winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response) !=
            NSS_STATUS_SUCCESS) {
-               return False;
+               return false;
        }
 
        /* Display response */
 
        d_printf("%s\n", response.data.winsresp);
 
-       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;
 
+       bool print_all = !list_all_domains && verbose;
+
        ZERO_STRUCT(request);
        ZERO_STRUCT(response);
 
@@ -334,43 +363,103 @@ static BOOL wbinfo_list_domains(BOOL list_all_domains)
 
        if (winbindd_request_response(WINBINDD_LIST_TRUSTDOM, &request, &response) !=
            NSS_STATUS_SUCCESS)
-               return False;
+               return false;
 
        /* Display response */
 
        if (response.extra_data.data) {
                const char *extra_data = (char *)response.extra_data.data;
-               fstring name;
-               char *p;
-
-               while(next_token(&extra_data, name, "\n", sizeof(fstring))) {
-                       p = strchr(name, '\\');
-                       if (p == 0) {
-                               d_fprintf(stderr, "Got invalid response: %s\n",
-                                        extra_data);
-                               return False;
+               char *name;
+               char *beg, *end;
+               TALLOC_CTX *frame = talloc_stackframe();
+
+               if (print_all) {
+                       d_printf("%-16s%-24s%-12s%-12s%-5s%-5s\n", 
+                                "Domain Name", "DNS Domain", "Trust Type", 
+                                "Transitive", "In", "Out");
+               }
+
+               while(next_token_talloc(frame,&extra_data,&name,"\n")) {
+                       /* Print Domain Name */
+                       if ((beg = strchr(name, '\\')) == NULL)
+                               goto error;
+                       *beg = 0;
+                       beg++;
+                       if ((end = strchr(beg, '\\')) == NULL)
+                               goto error;
+                       *end = 0;
+
+                       /* Print short name */
+
+                       d_printf("%-16s", name);
+
+                       if (!print_all) {
+                               d_printf("\n"); 
+                               continue;
+                       }
+
+                       /* Print DNS domain */
+
+                       if (beg) {
+                               d_printf("%-24s", beg);
                        }
-                       *p = 0;
-                       d_printf("%s\n", name);
+
+                       /* Skip SID */
+                       beg = ++end;
+                       if ((end = strchr(beg, '\\')) == NULL)
+                               goto error;
+
+                       /* Print Trust Type */
+                       beg = ++end;
+                       if ((end = strchr(beg, '\\')) == NULL)
+                               goto error;
+                       *end = 0;
+                       d_printf("%-12s", beg);
+
+                       /* Print Transitive */
+                       beg = ++end;
+                       if ((end = strchr(beg, '\\')) == NULL)
+                               goto error;
+                       *end = 0;
+                       d_printf("%-12s", beg);
+
+                       /* Print Incoming */
+                       beg = ++end;
+                       if ((end = strchr(beg, '\\')) == NULL)
+                               goto error;
+                       *end = 0;
+                       d_printf("%-5s", beg);
+
+                       /* Print Outgoing */
+                       beg = ++end;
+                       d_printf("%-5s\n", beg);
                }
+               goto out;
 
+error:
+               d_fprintf(stderr, "Got invalid response: %s\n", extra_data);
+               TALLOC_FREE(frame);
+               SAFE_FREE(response.extra_data.data);
+               return false;
+out:
+               TALLOC_FREE(frame);
                SAFE_FREE(response.extra_data.data);
        }
 
-       return True;
+       return true;
 }
 
 /* List own domain */
 
-static BOOL wbinfo_list_own_domain(void)
+static bool wbinfo_list_own_domain(void)
 {
        d_printf("%s\n", get_winbind_domain());
 
-       return True;
+       return true;
 }
 
 /* show sequence numbers */
-static BOOL wbinfo_show_sequence(const char *domain)
+static bool wbinfo_show_sequence(const char *domain)
 {
        struct winbindd_request  request;
        struct winbindd_response response;
@@ -385,62 +474,74 @@ static BOOL wbinfo_show_sequence(const char *domain)
 
        if (winbindd_request_response(WINBINDD_SHOW_SEQUENCE, &request, &response) !=
            NSS_STATUS_SUCCESS)
-               return False;
+               return false;
 
        /* Display response */
 
-       if (response.extra_data.data) {
+       if (domain) {
+               d_printf("%s : ", domain);
+               if (response.data.sequence_number == (uint32_t)-1) {
+                       d_printf("DISCONNECTED\n");
+               } else {
+                       d_printf("%d\n", response.data.sequence_number);
+               }
+       } else if (response.extra_data.data) {
                char *extra_data = (char *)response.extra_data.data;
                d_printf("%s", extra_data);
                SAFE_FREE(response.extra_data.data);
        }
 
-       return True;
+       return true;
 }
 
 /* Show domain info */
 
-static BOOL wbinfo_domain_info(const char *domain_name)
+static bool wbinfo_domain_info(const char *domain)
 {
-       struct winbindd_request request;
-       struct winbindd_response response;
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct wbcDomainInfo *dinfo = NULL;
+       char *sid_str = NULL;
 
-       ZERO_STRUCT(request);
-       ZERO_STRUCT(response);
-
-       if ((strequal(domain_name, ".")) || (domain_name[0] == '\0'))
-               fstrcpy(request.domain_name, get_winbind_domain());
-       else
-               fstrcpy(request.domain_name, domain_name);
+       if (strcmp(domain, ".") == 0 || domain[0] == '\0') {
+               domain = get_winbind_domain();
+       }
 
        /* Send request */
 
-       if (winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response) !=
-           NSS_STATUS_SUCCESS)
-               return False;
+       wbc_status = wbcDomainInfo(domain, &dinfo);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               return false;
+       }
+
+       wbc_status = wbcSidToString(&dinfo->sid, &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->flags & WBC_DOMINFO_AD) ? "Yes" : "No");
        d_printf("Native            : %s\n",
-                response.data.domain_info.native_mode ? "Yes" : "No");
+                (dinfo->flags & WBC_DOMINFO_NATIVE) ? "Yes" : "No");
 
        d_printf("Primary           : %s\n",
-                response.data.domain_info.primary ? "Yes" : "No");
+                (dinfo->flags & WBC_DOMINFO_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;
@@ -455,163 +556,218 @@ 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;
+       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;
 }
 
 /* Check trust account password */
 
-static BOOL wbinfo_check_secret(void)
+static bool wbinfo_check_secret(void)
 {
-        struct winbindd_response response;
-        NSS_STATUS result;
+       struct winbindd_response response;
+       NSS_STATUS result;
 
-        ZERO_STRUCT(response);
+       ZERO_STRUCT(response);
 
-        result = winbindd_request_response(WINBINDD_CHECK_MACHACC, NULL, &response);
-               
-       d_printf("checking the trust secret via RPC calls %s\n", 
+       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");
 
-       if (result != NSS_STATUS_SUCCESS)       
-               d_fprintf(stderr, "error code was %s (0x%x)\n", 
-                        response.data.auth.nt_status_string, 
+       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;    
 }
 
 /* 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);
+
+       wbcFreeMemory(sid_str);
 
-       return True;
+       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(char *sid)
 {
        struct winbindd_request request;
        struct winbindd_response response;
@@ -625,27 +781,27 @@ static BOOL wbinfo_lookupsid(char *sid)
 
        if (winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response) !=
            NSS_STATUS_SUCCESS)
-               return False;
+               return false;
 
        /* Display response */
 
-       d_printf("%s%c%s %d\n", response.data.name.dom_name, 
-                winbind_separator(), response.data.name.name, 
+       d_printf("%s%c%s %d\n", response.data.name.dom_name,
+                winbind_separator(), response.data.name.name,
                 response.data.name.type);
 
-       return True;
+       return true;
 }
 
 /* Lookup a list of RIDs */
 
-static BOOL wbinfo_lookuprids(char *domain, char *arg)
+static bool wbinfo_lookuprids(char *domain, char *arg)
 {
        size_t i;
        DOM_SID sid;
        int num_rids;
        uint32 *rids;
        const char *p;
-       char ridstr[32];
+       char *ridstr;
        const char **names;
        enum lsa_SidType *types;
        const char *domain_name;
@@ -666,39 +822,39 @@ static BOOL wbinfo_lookuprids(char *domain, char *arg)
        if (winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response) !=
            NSS_STATUS_SUCCESS) {
                d_printf("Could not get domain sid for %s\n", request.domain_name);
-               return False;
+               return false;
        }
 
        if (!string_to_sid(&sid, response.data.domain_info.sid)) {
                d_printf("Could not convert %s to sid\n", response.data.domain_info.sid);
-               return False;
+               return false;
        }
 
        mem_ctx = talloc_new(NULL);
        if (mem_ctx == NULL) {
                d_printf("talloc_new failed\n");
-               return False;
+               return false;
        }
 
        num_rids = 0;
        rids = NULL;
        p = arg;
 
-       while (next_token(&p, ridstr, " ,\n", sizeof(ridstr))) {
+       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) {
                TALLOC_FREE(mem_ctx);
-               return False;
+               return false;
        }
 
        if (!winbind_lookup_rids(mem_ctx, &sid, num_rids, rids,
                                 &domain_name, &names, &types)) {
                d_printf("winbind_lookup_rids failed\n");
                TALLOC_FREE(mem_ctx);
-               return False;
+               return false;
        }
 
        d_printf("Domain: %s\n", domain_name);
@@ -709,12 +865,12 @@ static BOOL wbinfo_lookuprids(char *domain, char *arg)
        }
 
        TALLOC_FREE(mem_ctx);
-       return True;
+       return true;
 }
 
 /* Convert string to sid */
 
-static BOOL wbinfo_lookupname(char *name)
+static bool wbinfo_lookupname(char *name)
 {
        struct winbindd_request request;
        struct winbindd_response response;
@@ -724,23 +880,23 @@ static BOOL wbinfo_lookupname(char *name)
        ZERO_STRUCT(request);
        ZERO_STRUCT(response);
 
-       parse_wbinfo_domain_user(name, request.data.name.dom_name, 
+       parse_wbinfo_domain_user(name, request.data.name.dom_name,
                                 request.data.name.name);
 
        if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response) !=
            NSS_STATUS_SUCCESS)
-               return False;
+               return false;
 
        /* Display response */
 
        d_printf("%s %s (%d)\n", response.data.sid.sid, sid_type_lookup(response.data.sid.type), response.data.sid.type);
 
-       return True;
+       return true;
 }
 
 /* Authenticate a user with a plaintext password */
 
-static BOOL wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
+static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
 {
        struct winbindd_request request;
        struct winbindd_response response;
@@ -784,8 +940,8 @@ static BOOL wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
        if (result == NSS_STATUS_SUCCESS) {
 
                if (request.flags & WBFLAG_PAM_INFO3_TEXT) {
-                       if (response.data.auth.info3.user_flgs & LOGON_CACHED_ACCOUNT) {
-                               d_printf("user_flgs: LOGON_CACHED_ACCOUNT\n");
+                       if (response.data.auth.info3.user_flgs & NETLOGON_CACHED_ACCOUNT) {
+                               d_printf("user_flgs: NETLOGON_CACHED_ACCOUNT\n");
                        }
                }
 
@@ -801,167 +957,167 @@ static BOOL wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
 
 /* Authenticate a user with a plaintext password */
 
-static BOOL wbinfo_auth(char *username)
+static bool wbinfo_auth(char *username)
 {
-       struct winbindd_request request;
-       struct winbindd_response response;
-        NSS_STATUS result;
-        char *p;
-
-       /* Send off request */
-
-       ZERO_STRUCT(request);
-       ZERO_STRUCT(response);
-
-        p = strchr(username, '%');
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       char *s = NULL;
+       char *p = NULL;
+       const char *password = NULL;
+       char *name = NULL;
+
+       if ((s = SMB_STRDUP(username)) == NULL) {
+               return false;
+       }
 
-        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 = strchr(s, '%')) != NULL) {
+               *p = 0;
+               p++;
+               password = p;
+       } else {
+               password = "";
+       }
 
-       result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response);
+       name = s;
 
-       /* Display response */
+       wbc_status = wbcAuthenticateUser(name, password);
 
-        d_printf("plaintext password authentication %s\n", 
-               (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
+       d_printf("plaintext password authentication %s\n",
+                WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
 
+#if 0
        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);
+#endif
+
+       SAFE_FREE(s);
 
-        return result == NSS_STATUS_SUCCESS;
+       return WBC_ERROR_IS_OK(wbc_status);
 }
 
 /* Authenticate a user with a challenge/response */
 
-static BOOL wbinfo_auth_crap(char *username)
+static bool wbinfo_auth_crap(char *username)
 {
-       struct winbindd_request request;
-       struct winbindd_response response;
-        NSS_STATUS result;
-        fstring name_user;
-        fstring name_domain;
-        fstring pass;
-        char *p;
-
-       /* Send off request */
-
-       ZERO_STRUCT(request);
-       ZERO_STRUCT(response);
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct wbcAuthUserParams params;
+       struct wbcAuthUserInfo *info = NULL;
+       struct wbcAuthErrorInfo *err = NULL;
+       DATA_BLOB lm = data_blob_null;
+       DATA_BLOB nt = data_blob_null;
+       fstring name_user;
+       fstring name_domain;
+       fstring pass;
+       char *p;
 
-        p = strchr(username, '%');
+       p = strchr(username, '%');
 
-        if (p) {
-                *p = 0;
-                fstrcpy(pass, p + 1);
+       if (p) {
+               *p = 0;
+               fstrcpy(pass, p + 1);
        }
                
        parse_wbinfo_domain_user(username, name_domain, name_user);
 
-       request.data.auth_crap.logon_parameters = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;
+       params.account_name     = name_user;
+       params.domain_name      = name_domain;
+       params.workstation_name = NULL;
+
+       params.flags            = 0;
+       params.parameter_control= WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT |
+                                 WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;
 
-       fstrcpy(request.data.auth_crap.user, name_user);
+       params.level            = WBC_AUTH_USER_LEVEL_RESPONSE;
 
-       fstrcpy(request.data.auth_crap.domain, 
-                             name_domain);
+       generate_random_buffer(params.password.response.challenge, 8);
 
-       generate_random_buffer(request.data.auth_crap.chal, 8);
-        
        if (lp_client_ntlmv2_auth()) {
                DATA_BLOB server_chal;
-               DATA_BLOB names_blob;   
+               DATA_BLOB names_blob;
 
-               DATA_BLOB lm_response;
-               DATA_BLOB nt_response;
+               server_chal = data_blob(params.password.response.challenge, 8);
 
-               server_chal = data_blob(request.data.auth_crap.chal, 8); 
-               
                /* Pretend this is a login to 'us', for blob purposes */
                names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup());
-               
-               if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal, 
+
+               if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal,
                                      &names_blob,
-                                     &lm_response, &nt_response, NULL)) {
+                                     &lm, &nt, NULL)) {
                        data_blob_free(&names_blob);
                        data_blob_free(&server_chal);
-                       return False;
+                       return false;
                }
                data_blob_free(&names_blob);
                data_blob_free(&server_chal);
 
-               memcpy(request.data.auth_crap.nt_resp, nt_response.data, 
-                      MIN(nt_response.length, 
-                          sizeof(request.data.auth_crap.nt_resp)));
-               request.data.auth_crap.nt_resp_len = nt_response.length;
-
-               memcpy(request.data.auth_crap.lm_resp, lm_response.data, 
-                      MIN(lm_response.length, 
-                          sizeof(request.data.auth_crap.lm_resp)));
-               request.data.auth_crap.lm_resp_len = lm_response.length;
-                      
-               data_blob_free(&nt_response);
-               data_blob_free(&lm_response);
-
        } else {
-               if (lp_client_lanman_auth() 
-                   && SMBencrypt(pass, request.data.auth_crap.chal, 
-                              (uchar *)request.data.auth_crap.lm_resp)) {
-                       request.data.auth_crap.lm_resp_len = 24;
-               } else {
-                       request.data.auth_crap.lm_resp_len = 0;
+               if (lp_client_lanman_auth()) {
+                       bool ok;
+                       lm = data_blob(NULL, 24);
+                       ok = SMBencrypt(pass, params.password.response.challenge,
+                                       lm.data);
+                       if (!ok) {
+                               data_blob_free(&lm);
+                       }
                }
-               SMBNTencrypt(pass, request.data.auth_crap.chal,
-                            (uchar *)request.data.auth_crap.nt_resp);
-
-               request.data.auth_crap.nt_resp_len = 24;
+               nt = data_blob(NULL, 24);
+               SMBNTencrypt(pass, params.password.response.challenge,
+                            nt.data);
        }
 
-       result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);
+       params.password.response.nt_length      = nt.length;
+       params.password.response.nt_data        = nt.data;
+       params.password.response.lm_length      = lm.length;
+       params.password.response.lm_data        = lm.data;
+
+       wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
 
        /* Display response */
 
-        d_printf("challenge/response password authentication %s\n", 
-               (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
+       d_printf("challenge/response password authentication %s\n",
+                WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
 
-       if (response.data.auth.nt_status)
+       if (wbc_status == WBC_ERR_AUTH_ERROR) {
                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,
-                        response.data.auth.error_string);
+                        err->nt_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: "));
        }
 
@@ -971,114 +1127,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 domain */
-               if ( strequal(domain, ".") )
-                       fstrcpy( request.domain_name, get_winbind_domain() );
-               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 */
+       wbc_status = wbcListUsers(domain, &num_users, &users);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               return false;
+       }
 
-       if (!response.extra_data.data)
-               return False;
+       for (i=0; i < num_users; i++) {
+               d_printf("%s\n", users[i]);
+       }
 
-       extra_data = (const char *)response.extra_data.data;
+       wbcFreeMemory(users);
 
-       while(next_token(&extra_data, name, ",", sizeof(fstring)))
-               d_printf("%s\n", name);
-       
-       SAFE_FREE(response.extra_data.data);
-
-       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, get_winbind_domain() );
-               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;
@@ -1096,7 +1233,7 @@ static BOOL wbinfo_set_auth_user(char *username)
        } else {
                char *thepass = getpass("Password: ");
                if (thepass) {
-                       password = thepass;     
+                       password = thepass;
                } else
                        password = "";
        }
@@ -1110,7 +1247,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
@@ -1119,7 +1256,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 {
@@ -1132,13 +1269,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)
@@ -1146,7 +1283,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)){
@@ -1168,18 +1305,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 */
@@ -1190,6 +1327,7 @@ enum {
        OPT_DOMAIN_NAME,
        OPT_SEQUENCE,
        OPT_GETDCNAME,
+       OPT_DSGETDCNAME,
        OPT_USERDOMGROUPS,
        OPT_USERSIDS,
        OPT_ALLOCATE_UID,
@@ -1197,23 +1335,26 @@ enum {
        OPT_SEPARATOR,
        OPT_LIST_ALL_DOMAINS,
        OPT_LIST_OWN_DOMAIN,
+       OPT_UID_INFO,
        OPT_GROUP_INFO,
+       OPT_VERBOSE
 };
 
 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"},
@@ -1238,6 +1379,7 @@ int main(int argc, char **argv, char **envp)
                { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" },
                { "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,
@@ -1247,6 +1389,7 @@ int main(int argc, char **argv, char **envp)
                { "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" },
@@ -1259,6 +1402,8 @@ int main(int argc, char **argv, char **envp)
                        /* "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
        };
@@ -1266,16 +1411,6 @@ int main(int argc, char **argv, char **envp)
        /* 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 */
 
@@ -1290,10 +1425,26 @@ int main(int argc, char **argv, char **envp)
 
        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);
 
@@ -1387,7 +1538,7 @@ int main(int argc, char **argv, char **envp)
                        }
                        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;
                        }
@@ -1411,6 +1562,13 @@ int main(int argc, char **argv, char **envp)
                                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 "
@@ -1440,18 +1598,18 @@ int main(int argc, char **argv, char **envp)
                        }
                        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)
@@ -1459,37 +1617,16 @@ int main(int argc, char **argv, char **envp)
                                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':
@@ -1517,8 +1654,13 @@ int main(int argc, char **argv, char **envp)
                                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;
                        }
@@ -1526,7 +1668,7 @@ int main(int argc, char **argv, char **envp)
                        break;
                }
                case OPT_LIST_ALL_DOMAINS:
-                       if (!wbinfo_list_domains(True)) {
+                       if (!wbinfo_list_domains(true, verbose)) {
                                goto done;
                        }
                        break;
@@ -1538,6 +1680,8 @@ int main(int argc, char **argv, char **envp)
                /* generic configuration options */
                case OPT_DOMAIN_NAME:
                        break;
+               case OPT_VERBOSE:
+                       break;
                default:
                        d_fprintf(stderr, "Invalid option\n");
                        poptPrintHelp(pc, stderr, 0);
@@ -1550,6 +1694,8 @@ int main(int argc, char **argv, char **envp)
        /* Exit code */
 
  done:
+       talloc_destroy(frame);
+
        poptFreeContext(pc);
        return result;
 }