/* Editor Settings: expandtabs and use 4 spaces for indentation
* ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
* -*- mode: c, c-basic-offset: 4 -*- */
/*
* Copyright Likewise Software 2004-2008
* All rights reserved.
*
* 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 (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the 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, see
* .
*
* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
* GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
* license@likewisesoftware.com
*/
#include
#include
#include
#include
#include "wbclient.h"
#define BAIL_ON_WBC_ERR(x) \
do { \
if (x != WBC_ERR_SUCCESS) { \
goto done; \
} \
} while (0);
static bool split_name(const char *name, char **domain, char **account)
{
char *pszCopy;
char *p;
if ((pszCopy = strdup(name)) == NULL) {
return false;
}
if ((p = strchr(pszCopy, '\\')) == NULL) {
free(pszCopy);
return false;
}
*p = '\0';
*domain = strdup(pszCopy);
*account = strdup(p+1);
free(pszCopy);
return true;
}
void PrintStructPasswd(struct passwd *pw)
{
printf("%s:%s:%u:%u:%s:%s:%s\n",
pw->pw_name,
pw->pw_passwd,
(unsigned int)pw->pw_uid,
(unsigned int)pw->pw_gid,
pw->pw_gecos ? pw->pw_gecos : "",
pw->pw_dir,
pw->pw_shell);
return;
}
void PrintStructGroup(struct group *gr)
{
int i = 0;
printf("%s:%s:%u:",
gr->gr_name,
gr->gr_passwd,
(unsigned int)gr->gr_gid);
for (i=0; gr->gr_mem[i]; i++) {
printf("%s,", gr->gr_mem[i]);
}
printf("\n");
return;
}
static int LookupUser(char *name)
{
int ret = 0;
struct passwd *pw;
wbcErr wbc_status;
uid_t uid;
wbc_status = wbcGetpwnam(name, &pw);
BAIL_ON_WBC_ERR(wbc_status);
PrintStructPasswd(pw);
uid = pw->pw_uid;
wbcFreeMemory(pw);
pw = NULL;
wbc_status = wbcGetpwuid(uid, &pw);
BAIL_ON_WBC_ERR(wbc_status);
PrintStructPasswd(pw);
wbcFreeMemory(pw);
pw = NULL;
done:
if (!WBC_ERROR_IS_OK(wbc_status)) {
printf("LookupUser: Result was %s\n",
wbcErrorString(wbc_status));
ret = 1;
}
if (pw) {
wbcFreeMemory(pw);
}
return ret;
}
static int LookupGroup(char *name)
{
int ret = 0;
struct group *gr = NULL;
wbcErr wbc_status;
gid_t gid;
wbc_status = wbcGetgrnam(name, &gr);
BAIL_ON_WBC_ERR(wbc_status);
PrintStructGroup(gr);
gid = gr->gr_gid;
wbcFreeMemory(gr);
gr = NULL;
wbc_status = wbcGetgrgid(gid, &gr);
BAIL_ON_WBC_ERR(wbc_status);
PrintStructGroup(gr);
wbcFreeMemory(gr);
gr = NULL;
done:
if (!WBC_ERROR_IS_OK(wbc_status)) {
printf("LookupGroup: Result was %s\n",
wbcErrorString(wbc_status));
ret = 1;
}
if (gr) {
wbcFreeMemory(gr);
}
return ret;
}
int LookupUserGroups(const char *name)
{
wbcErr wbc_status;
uint32_t num_groups = 0;
gid_t *gids = NULL;
int i;
struct wbcDomainSid user_sid;
enum wbcSidType type;
struct wbcDomainSid *sidList = NULL;
uint32_t num_sids = 0;
char *sid_string = NULL;
char *domain = NULL;
char *account = NULL;
wbc_status = wbcGetGroups(name, &num_groups, &gids);
BAIL_ON_WBC_ERR(wbc_status);
for (i=0; igr_name, (unsigned int)gr->gr_gid);
wbcFreeMemory(gr);
gr = NULL;
}
if (!split_name(name, &domain, &account)) {
printf("Failed to parse %s\n", name);
return 1;
}
printf("\n");
wbc_status = wbcLookupName(domain, account, &user_sid, &type);
BAIL_ON_WBC_ERR(wbc_status);
if (type != WBC_SID_NAME_USER) {
wbc_status = WBC_ERR_INVALID_SID;
BAIL_ON_WBC_ERR(wbc_status);
}
free(domain);
free(account);
domain = account = NULL;
wbc_status = wbcLookupUserSids(&user_sid, true, &num_sids, &sidList);
BAIL_ON_WBC_ERR(wbc_status);
for (i=0; i %s\n", sid_string);
printf(" Derived -> %s\n", sid_string2);
goto done;
}
printf("%s <-> %u\n", sid_string2, (unsigned int)uid);
done:
if (wbc_status != WBC_ERR_SUCCESS) {
printf("MapSidToUid Failed (%s)\n", wbcErrorString(wbc_status));
}
if (sid_string2)
wbcFreeMemory(sid_string2);
return;
}
static void MapSidToGid(const char *sid_string)
{
wbcErr wbc_status;
struct wbcDomainSid sid;
struct wbcDomainSid sid2;
gid_t gid;
char *sid_string2 = NULL;
memset(&sid, 0x0, sizeof(struct wbcDomainSid));
memset(&sid2, 0x0, sizeof(struct wbcDomainSid));
wbc_status = wbcStringToSid(sid_string, &sid);
BAIL_ON_WBC_ERR(wbc_status);
wbc_status = wbcSidToGid(&sid, &gid);
BAIL_ON_WBC_ERR(wbc_status);
wbc_status = wbcGidToSid(gid, &sid2);
BAIL_ON_WBC_ERR(wbc_status);
wbc_status = wbcSidToString(&sid2, &sid_string2);
BAIL_ON_WBC_ERR(wbc_status);
if (strcmp(sid_string, sid_string2) != 0) {
printf("Sids do not match!\n");
printf(" Original -> %s\n", sid_string);
printf(" Derived -> %s\n", sid_string2);
goto done;
}
printf("%s <-> %u\n", sid_string2, (unsigned int)gid);
done:
if (wbc_status != WBC_ERR_SUCCESS) {
printf("MapSidToGid Failed (%s)\n", wbcErrorString(wbc_status));
}
if (sid_string2)
wbcFreeMemory(sid_string2);
return;
}
int LookupName(const char *name)
{
int ret = 0;
wbcErr wbc_status;
char *domain = NULL;
char *account = NULL;
struct wbcDomainSid sid;
char *sid_string;
enum wbcSidType type;
if (!split_name(name, &domain, &account)) {
return 1;
}
wbc_status = wbcLookupName(domain, account, &sid, &type);
BAIL_ON_WBC_ERR(wbc_status);
wbc_status = wbcSidToString(&sid, &sid_string);
BAIL_ON_WBC_ERR(wbc_status);
printf("%s (%d)\n", sid_string, type);
free(domain);
free(account);
domain = account = NULL;
wbc_status = wbcLookupSid(&sid, &domain, &account, &type);
BAIL_ON_WBC_ERR(wbc_status);
printf("%s\\%s (%d)\n", domain, account, type);
switch (type) {
case WBC_SID_NAME_USER:
MapSidToUid(sid_string);
break;
case WBC_SID_NAME_DOM_GRP:
MapSidToGid(sid_string);
break;
default:
printf("unknown SID type\n");
}
wbcFreeMemory(sid_string);
wbcFreeMemory(domain);
wbcFreeMemory(account);
sid_string = domain = account = NULL;
ret = 0;
done:
if (!WBC_ERROR_IS_OK(wbc_status)) {
printf("LookupName: Result was %s\n",
wbcErrorString(wbc_status));
ret = 1;
}
if (domain)
free(domain);
if (account)
free(account);
return ret;
}
static int InterfaceDetails(void)
{
struct wbcInterfaceDetails *iface = NULL;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
wbc_status = wbcInterfaceDetails(&iface);
BAIL_ON_WBC_ERR(wbc_status);
printf("Interface Version = %d\n", iface->interface_version);
printf("Winbind Version = %s\n", iface->winbind_version);
printf("Separator = %c\n", iface->winbind_separator);
printf("My name = %s\n", iface->netbios_name);
printf("My domain = %s\n", iface->netbios_domain);
printf("My DNS domain = %s\n", iface->dns_domain);
done:
if (iface)
wbcFreeMemory(iface);
return 0;
}
static int ListGroups(void)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
const char **ppszGroupList = NULL;
uint32_t nGroups = 0;
int i;
wbc_status = wbcListGroups(NULL, &nGroups, &ppszGroupList);
BAIL_ON_WBC_ERR(wbc_status);
for (i=0; i= argc)
return 1;
i++;
LookupGroup(argv[i++]);
continue;
}
if (strcmp(argv[i], "--getpwnam") == 0) {
if (i+1 >= argc)
return 1;
i++;
LookupUser(argv[i++]);
continue;
}
if (strcmp(argv[i], "--usergroups") == 0) {
if (i+1 >= argc)
return 1;
i++;
LookupUserGroups(argv[i++]);
continue;
}
if (strcmp(argv[i], "--lookupname") == 0) {
if (i+1 >= argc)
return 1;
i++;
LookupName(argv[i++]);
continue;
}
if (strcmp(argv[i], "--interface") == 0) {
i++;
InterfaceDetails();
continue;
}
if (strcmp(argv[i], "--listgroups") == 0) {
i++;
ListGroups();
continue;
}
if (strcmp(argv[i], "--listusers") == 0) {
i++;
ListUsers();
continue;
}
/* Unparseable option */
return 1;
}
return 0;
}
static void PrintUsage(const char *program)
{
printf("%s [options]\n", program);
printf("\t--getpwnam Perform forward and reverse lookups of a user\n");
printf("\t--getgrnam Perform forward and reverse lookups of a group\n");
printf("\t--usergroups Print a list of the user's group membership\n");
printf("\t--lookupname Convert a name to a SID\n");
printf("\t--interface Print out Library interface details\n");
printf("\t--listgroups List the groups in all know domains\n");
printf("\t--listusers List the users in all know domains\n");
printf("\n");
return;
}
int main(int argc, char *argv[])
{
int ret;
/* Parse options starting at first real parameters */
if ((ret = ParseArgs(argc-1, &argv[1])) != 0) {
PrintUsage(argv[0]);
}
return ret;
}