Make wbinfo also print the members when querying a group
[ira/wip.git] / nsswitch / wbinfo.c
index 36c2818ccf26b91a4a34528cdebd5f50def59ff4..ac5b4c43951cfe0aa4b6e916c0b57b65d13e1809 100644 (file)
@@ -23,6 +23,7 @@
 #include "includes.h"
 #include "winbind_client.h"
 #include "libwbclient/wbclient.h"
+#include "../libcli/auth/libcli_auth.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
@@ -167,11 +168,11 @@ static bool wbinfo_get_userinfo(char *user)
                return false;
        }
 
-       d_printf("%s:%s:%d:%d:%s:%s:%s\n",
+       d_printf("%s:%s:%u:%u:%s:%s:%s\n",
                 pwd->pw_name,
                 pwd->pw_passwd,
-                pwd->pw_uid,
-                pwd->pw_gid,
+                (unsigned int)pwd->pw_uid,
+                (unsigned int)pwd->pw_gid,
                 pwd->pw_gecos,
                 pwd->pw_dir,
                 pwd->pw_shell);
@@ -190,11 +191,11 @@ static bool wbinfo_get_uidinfo(int uid)
                return false;
        }
 
-       d_printf("%s:%s:%d:%d:%s:%s:%s\n",
+       d_printf("%s:%s:%u:%u:%s:%s:%s\n",
                 pwd->pw_name,
                 pwd->pw_passwd,
-                pwd->pw_uid,
-                pwd->pw_gid,
+                (unsigned int)pwd->pw_uid,
+                (unsigned int)pwd->pw_gid,
                 pwd->pw_gecos,
                 pwd->pw_dir,
                 pwd->pw_shell);
@@ -202,21 +203,83 @@ static bool wbinfo_get_uidinfo(int uid)
        return true;
 }
 
+static bool wbinfo_get_user_sidinfo(const char *sid_str)
+{
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct passwd *pwd = NULL;
+       struct wbcDomainSid sid;
+
+       wbc_status = wbcStringToSid(sid_str, &sid);
+       wbc_status = wbcGetpwsid(&sid, &pwd);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               return false;
+       }
+
+       d_printf("%s:%s:%u:%u:%s:%s:%s\n",
+                pwd->pw_name,
+                pwd->pw_passwd,
+                (unsigned int)pwd->pw_uid,
+                (unsigned int)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)
 {
        wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
        struct group *grp;
+       char **mem;
 
        wbc_status = wbcGetgrnam(group, &grp);
        if (!WBC_ERROR_IS_OK(wbc_status)) {
                return false;
        }
 
-       d_printf("%s:%s:%d\n",
+       d_printf("%s:%s:%u:",
+                grp->gr_name,
+                grp->gr_passwd,
+                (unsigned int)grp->gr_gid);
+
+       mem = grp->gr_mem;
+       while (*mem != NULL) {
+               d_printf("%s%s", *mem, *(mem+1) != NULL ? "," : "");
+               mem += 1;
+       }
+       d_printf("\n");
+
+       wbcFreeMemory(grp);
+
+       return true;
+}
+
+/* pull grent for a given gid */
+static bool wbinfo_get_gidinfo(int gid)
+{
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct group *grp;
+       char **mem;
+
+       wbc_status = wbcGetgrgid(gid, &grp);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               return false;
+       }
+
+       d_printf("%s:%s:%u:",
                 grp->gr_name,
                 grp->gr_passwd,
-                grp->gr_gid);
+                (unsigned int)grp->gr_gid);
+
+       mem = grp->gr_mem;
+       while (*mem != NULL) {
+               d_printf("%s%s", *mem, *(mem+1) != NULL ? "," : "");
+               mem += 1;
+       }
+       d_printf("\n");
 
        wbcFreeMemory(grp);
 
@@ -320,6 +383,64 @@ static bool wbinfo_get_userdomgroups(const char *user_sid_str)
        return true;
 }
 
+static bool wbinfo_get_sidaliases(const char *domain,
+                                 const char *user_sid_str)
+{
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct wbcDomainInfo *dinfo = NULL;
+       uint32_t i;
+       struct wbcDomainSid user_sid;
+       uint32_t *alias_rids = NULL;
+       uint32_t num_alias_rids;
+       char *domain_sid_str = NULL;
+
+       /* Send request */
+       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;
+       }
+       wbc_status = wbcStringToSid(user_sid_str, &user_sid);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               goto done;
+       }
+
+       wbc_status = wbcGetSidAliases(&dinfo->sid, &user_sid, 1,
+           &alias_rids, &num_alias_rids);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               goto done;
+       }
+
+       wbc_status = wbcSidToString(&dinfo->sid, &domain_sid_str);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               goto done;
+       }
+
+       for (i = 0; i < num_alias_rids; i++) {
+               d_printf("%s-%d\n", domain_sid_str, alias_rids[i]);
+       }
+
+       wbcFreeMemory(alias_rids);
+
+done:
+       if (domain_sid_str) {
+               wbcFreeMemory(domain_sid_str);
+       }
+       if (dinfo) {
+               wbcFreeMemory(dinfo);
+       }
+       return (WBC_ERR_SUCCESS == wbc_status);
+}
+
+
 /* Convert NetBIOS name to IP */
 
 static bool wbinfo_wins_byname(const char *name)
@@ -739,7 +860,7 @@ static bool wbinfo_allocate_uid(void)
 
        /* Display response */
 
-       d_printf("New uid: %d\n", uid);
+       d_printf("New uid: %u\n", (unsigned int)uid);
 
        return true;
 }
@@ -758,7 +879,7 @@ static bool wbinfo_allocate_gid(void)
 
        /* Display response */
 
-       d_printf("New gid: %d\n", gid);
+       d_printf("New gid: %u\n", (unsigned int)gid);
 
        return true;
 }
@@ -782,7 +903,8 @@ static bool wbinfo_set_uid_mapping(uid_t uid, const char *sid_str)
 
        /* Display response */
 
-       d_printf("uid %d now mapped to sid %s\n", uid, sid_str);
+       d_printf("uid %u now mapped to sid %s\n",
+               (unsigned int)uid, sid_str);
 
        return true;
 }
@@ -806,7 +928,8 @@ static bool wbinfo_set_gid_mapping(gid_t gid, const char *sid_str)
 
        /* Display response */
 
-       d_printf("gid %d now mapped to sid %s\n", gid, sid_str);
+       d_printf("gid %u now mapped to sid %s\n",
+               (unsigned int)gid, sid_str);
 
        return true;
 }
@@ -830,7 +953,8 @@ static bool wbinfo_remove_uid_mapping(uid_t uid, const char *sid_str)
 
        /* Display response */
 
-       d_printf("Removed uid %d to sid %s mapping\n", uid, sid_str);
+       d_printf("Removed uid %u to sid %s mapping\n",
+               (unsigned int)uid, sid_str);
 
        return true;
 }
@@ -854,7 +978,8 @@ static bool wbinfo_remove_gid_mapping(gid_t gid, const char *sid_str)
 
        /* Display response */
 
-       d_printf("Removed gid %d to sid %s mapping\n", gid, sid_str);
+       d_printf("Removed gid %u to sid %s mapping\n",
+               (unsigned int)gid, sid_str);
 
        return true;
 }
@@ -1069,66 +1194,107 @@ static char *wbinfo_prompt_pass(const char *prefix,
 
 static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
 {
-       struct winbindd_request request;
-       struct winbindd_response response;
-       NSS_STATUS result;
-       char *p;
-       char *password;
-
-       /* Send off request */
-
-       ZERO_STRUCT(request);
-       ZERO_STRUCT(response);
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       char *s = NULL;
+       char *p = NULL;
+       char *password = NULL;
+       char *name = NULL;
+       uid_t uid;
+       struct wbcLogonUserParams params;
+       struct wbcLogonUserInfo *info;
+       struct wbcAuthErrorInfo *error;
+       struct wbcUserPasswordPolicyInfo *policy;
 
-       p = strchr(username, '%');
+       if ((s = SMB_STRDUP(username)) == NULL) {
+               return false;
+       }
 
-       if (p) {
+       if ((p = strchr(s, '%')) != NULL) {
                *p = 0;
-               fstrcpy(request.data.auth.user, username);
-               fstrcpy(request.data.auth.pass, p + 1);
-               *p = '%';
+               p++;
+               password = SMB_STRDUP(p);
        } else {
-               fstrcpy(request.data.auth.user, username);
                password = wbinfo_prompt_pass(NULL, username);
-               fstrcpy(request.data.auth.pass, password);
-               SAFE_FREE(password);
        }
 
-       request.flags = flags;
+       name = s;
 
-       fstrcpy(request.data.auth.krb5_cc_type, cctype);
+       uid = geteuid();
 
-       request.data.auth.uid = geteuid();
+       params.username = name;
+       params.password = password;
+       params.num_blobs = 0;
+       params.blobs = NULL;
 
-       result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response);
+       wbc_status = wbcAddNamedBlob(&params.num_blobs,
+                                    &params.blobs,
+                                    "flags",
+                                    0,
+                                    (uint8_t *)&flags,
+                                    sizeof(flags));
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               goto done;
+       }
 
-       /* Display response */
+       wbc_status = wbcAddNamedBlob(&params.num_blobs,
+                                    &params.blobs,
+                                    "user_uid",
+                                    0,
+                                    (uint8_t *)&uid,
+                                    sizeof(uid));
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               goto done;
+       }
+
+       wbc_status = wbcAddNamedBlob(&params.num_blobs,
+                                    &params.blobs,
+                                    "krb5_cc_type",
+                                    0,
+                                    (uint8_t *)cctype,
+                                    strlen(cctype)+1);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               goto done;
+       }
+
+       wbc_status = wbcLogonUser(&params, &info, &error, &policy);
 
        d_printf("plaintext kerberos password authentication for [%s] %s (requesting cctype: %s)\n",
-               username, (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", cctype);
+                username, WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed", cctype);
 
-       if (response.data.auth.nt_status)
+       if (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);
-
-       if (result == NSS_STATUS_SUCCESS) {
+                        error->nt_string,
+                        error->nt_status,
+                        error->display_string);
+       }
 
-               if (request.flags & WBFLAG_PAM_INFO3_TEXT) {
-                       if (response.data.auth.info3.user_flgs & NETLOGON_CACHED_ACCOUNT) {
+       if (WBC_ERROR_IS_OK(wbc_status)) {
+               if (flags & WBFLAG_PAM_INFO3_TEXT) {
+                       if (info && info->info && info->info->user_flags & NETLOGON_CACHED_ACCOUNT) {
                                d_printf("user_flgs: NETLOGON_CACHED_ACCOUNT\n");
                        }
                }
 
-               if (response.data.auth.krb5ccname[0] != '\0') {
-                       d_printf("credentials were put in: %s\n", response.data.auth.krb5ccname);
+               if (info) {
+                       int i;
+                       for (i=0; i < info->num_blobs; i++) {
+                               if (strequal(info->blobs[i].name, "krb5ccname")) {
+                                       d_printf("credentials were put in: %s\n",
+                                               (const char *)info->blobs[i].blob.data);
+                                       break;
+                               }
+                       }
                } else {
                        d_printf("no credentials cached\n");
                }
        }
+ done:
 
-       return result == NSS_STATUS_SUCCESS;
+       SAFE_FREE(s);
+       SAFE_FREE(password);
+       wbcFreeMemory(params.blobs);
+
+       return WBC_ERROR_IS_OK(wbc_status);
 }
 
 /* Authenticate a user with a plaintext password */
@@ -1219,11 +1385,11 @@ static bool wbinfo_auth_crap(char *username)
                server_chal = data_blob(params.password.response.challenge, 8);
 
                /* Pretend this is a login to 'us', for blob purposes */
-               names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup());
+               names_blob = NTLMv2_generate_names_blob(NULL, global_myname(), lp_workgroup());
 
-               if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal,
+               if (!SMBNTLMv2encrypt(NULL, name_user, name_domain, pass, &server_chal,
                                      &names_blob,
-                                     &lm, &nt, NULL)) {
+                                     &lm, &nt, NULL, NULL)) {
                        data_blob_free(&names_blob);
                        data_blob_free(&server_chal);
                        SAFE_FREE(pass);
@@ -1532,6 +1698,7 @@ enum {
        OPT_GETDCNAME,
        OPT_DSGETDCNAME,
        OPT_USERDOMGROUPS,
+       OPT_SIDALIASES,
        OPT_USERSIDS,
        OPT_ALLOCATE_UID,
        OPT_ALLOCATE_GID,
@@ -1543,7 +1710,9 @@ enum {
        OPT_LIST_ALL_DOMAINS,
        OPT_LIST_OWN_DOMAIN,
        OPT_UID_INFO,
+       OPT_USER_SIDINFO,
        OPT_GROUP_INFO,
+       OPT_GID_INFO,
        OPT_VERBOSE,
        OPT_ONLINESTATUS,
        OPT_CHANGE_USER_PASSWORD,
@@ -1600,9 +1769,12 @@ int main(int argc, char **argv, char **envp)
                { "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-sidinfo", 0, POPT_ARG_STRING, &string_arg, OPT_USER_SIDINFO, "Get user info from sid", "SID" },
+               { "gid-info", 0, POPT_ARG_INT, &int_arg, OPT_GID_INFO, "Get group info from gid", "GID" },
                { "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" },
+               { "sid-aliases", 0, POPT_ARG_STRING, &string_arg, OPT_SIDALIASES, "Get sid aliases", "SID" },
                { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" },
                { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
                { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
@@ -1837,6 +2009,13 @@ int main(int argc, char **argv, char **envp)
                                goto done;
                        }
                        break;
+               case OPT_USER_SIDINFO:
+                       if ( !wbinfo_get_user_sidinfo(string_arg)) {
+                               d_fprintf(stderr, "Could not get info for user sid %s\n",
+                                   string_arg);
+                               goto done;
+                       }
+                       break;
                case OPT_UID_INFO:
                        if ( !wbinfo_get_uidinfo(int_arg)) {
                                d_fprintf(stderr, "Could not get info for uid "
@@ -1851,6 +2030,13 @@ int main(int argc, char **argv, char **envp)
                                goto done;
                        }
                        break;
+               case OPT_GID_INFO:
+                       if ( !wbinfo_get_gidinfo(int_arg)) {
+                               d_fprintf(stderr, "Could not get info for gid "
+                                               "%d\n", int_arg);
+                               goto done;
+                       }
+                       break;
                case 'r':
                        if (!wbinfo_get_usergroups(string_arg)) {
                                d_fprintf(stderr, "Could not get groups for user %s\n",
@@ -1872,6 +2058,13 @@ int main(int argc, char **argv, char **envp)
                                goto done;
                        }
                        break;
+               case OPT_SIDALIASES:
+                       if (!wbinfo_get_sidaliases(opt_domain_name, string_arg)) {
+                               d_fprintf(stderr, "Could not get sid aliases "
+                                        "for user SID %s\n", string_arg);
+                               goto done;
+                       }
+                       break;
                case 'a': {
                                bool got_error = false;
 
@@ -1895,7 +2088,8 @@ int main(int argc, char **argv, char **envp)
                                uint32 flags =  WBFLAG_PAM_KRB5 |
                                                WBFLAG_PAM_CACHED_LOGIN |
                                                WBFLAG_PAM_FALLBACK_AFTER_KRB5 |
-                                               WBFLAG_PAM_INFO3_TEXT;
+                                               WBFLAG_PAM_INFO3_TEXT |
+                                               WBFLAG_PAM_CONTACT_TRUSTDOM;
 
                                if (!wbinfo_auth_krb5(string_arg, "FILE", flags)) {
                                        d_fprintf(stderr, "Could not authenticate user [%s] with "