#include "includes.h"
#include "nsswitch/winbind_nss.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
extern DOM_SID global_sid_NULL;
NSS_STATUS winbindd_request(int req_type,
struct winbindd_request *request,
struct winbindd_response *response);
BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
enum SID_NAME_USE *name_type)
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
if (!sid || !name_type)
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
fstrcpy(request.data.name.dom_name, dom_name);
fstrcpy(request.data.name.name, name);
if ((result = winbindd_request(WINBINDD_LOOKUPNAME, &request,
&response)) == NSS_STATUS_SUCCESS) {
if (!string_to_sid(sid, response.data.sid.sid))
return False;
*name_type = (enum SID_NAME_USE)response.data.sid.type;
}
return result == NSS_STATUS_SUCCESS;
}
BOOL winbind_lookup_sid(const DOM_SID *sid,
fstring dom_name, fstring name,
enum SID_NAME_USE *name_type)
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
fstring sid_str;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
sid_to_string(sid_str, sid);
fstrcpy(request.data.sid, sid_str);
result = winbindd_request(WINBINDD_LOOKUPSID, &request, &response);
if (result == NSS_STATUS_SUCCESS) {
fstrcpy(dom_name, response.data.name.dom_name);
fstrcpy(name, response.data.name.name);
*name_type = (enum SID_NAME_USE)response.data.name.type;
DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
sid_str, dom_name, name));
}
return (result == NSS_STATUS_SUCCESS);
}
BOOL winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
fstring sid_str;
if (!puid)
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
sid_to_string(sid_str, sid);
fstrcpy(request.data.sid, sid_str);
result = winbindd_request(WINBINDD_SID_TO_UID, &request, &response);
if (result == NSS_STATUS_SUCCESS) {
*puid = response.data.uid;
}
return (result == NSS_STATUS_SUCCESS);
}
BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
if (!sid)
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
request.data.uid = uid;
result = winbindd_request(WINBINDD_UID_TO_SID, &request, &response);
if (result == NSS_STATUS_SUCCESS) {
if (!string_to_sid(sid, response.data.sid.sid))
return False;
} else {
sid_copy(sid, &global_sid_NULL);
}
return (result == NSS_STATUS_SUCCESS);
}
BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
fstring sid_str;
if (!pgid)
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
sid_to_string(sid_str, sid);
fstrcpy(request.data.sid, sid_str);
result = winbindd_request(WINBINDD_SID_TO_GID, &request, &response);
if (result == NSS_STATUS_SUCCESS) {
*pgid = response.data.gid;
}
return (result == NSS_STATUS_SUCCESS);
}
BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
if (!sid)
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
request.data.gid = gid;
result = winbindd_request(WINBINDD_GID_TO_SID, &request, &response);
if (result == NSS_STATUS_SUCCESS) {
if (!string_to_sid(sid, response.data.sid.sid))
return False;
} else {
sid_copy(sid, &global_sid_NULL);
}
return (result == NSS_STATUS_SUCCESS);
}
BOOL winbind_allocate_rid(uint32 *rid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
result = winbindd_request(WINBINDD_ALLOCATE_RID, &request, &response);
if (result != NSS_STATUS_SUCCESS)
return False;
*rid = response.data.rid;
return True;
}
static int wb_getgroups(const char *user, gid_t **groups)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
ZERO_STRUCT(request);
fstrcpy(request.data.username, user);
ZERO_STRUCT(response);
result = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
if (result == NSS_STATUS_SUCCESS) {
*groups = (gid_t *)response.extra_data;
return response.data.num_entries;
}
return -1;
}
int winbind_initgroups(char *user, gid_t gid)
{
gid_t *tgr, *groups = NULL;
int result;
if (!strchr(user, *lp_winbind_separator())) {
return initgroups(user, gid);
}
result = wb_getgroups(user, &groups);
DEBUG(10,("winbind_getgroups: %s: result = %s\n", user,
result == -1 ? "FAIL" : "SUCCESS"));
if (result != -1) {
int ngroups = result, i;
BOOL is_member = False;
for (i = 0; i < ngroups; i++) {
if (groups[i] == gid) {
is_member = True;
}
}
if (!is_member) {
tgr = SMB_REALLOC_ARRAY(groups, gid_t, ngroups + 1);
if (!tgr) {
errno = ENOMEM;
result = -1;
goto done;
}
else groups = tgr;
groups[ngroups] = gid;
ngroups++;
}
if (sys_setgroups(ngroups, groups) == -1) {
errno = EPERM;
result = -1;
goto done;
}
} else {
errno = EIO;
}
done:
SAFE_FREE(groups);
return result;
}
int winbind_getgroups(const char *user, gid_t **list)
{
if (!(strchr(user, *lp_winbind_separator()) || lp_winbind_use_default_domain()))
return -1;
return wb_getgroups(user, list);
}
BOOL winbind_ping( void )
{
NSS_STATUS result;
result = winbindd_request(WINBINDD_PING, NULL, NULL);
return result == NSS_STATUS_SUCCESS;
}
BOOL winbind_create_user( const char *name, uint32 *rid )
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
if ( !lp_winbind_enable_local_accounts() )
return False;
if ( !name )
return False;
DEBUG(10,("winbind_create_user: %s\n", name));
ZERO_STRUCT(request);
ZERO_STRUCT(response);
if ( rid )
request.flags = WBFLAG_ALLOCATE_RID;
fstrcpy( request.data.acct_mgt.username, name );
fstrcpy( request.data.acct_mgt.groupname, "" );
result = winbindd_request( WINBINDD_CREATE_USER, &request, &response);
if ( rid )
*rid = response.data.rid;
return result == NSS_STATUS_SUCCESS;
}
BOOL winbind_create_group( const char *name, uint32 *rid )
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
if ( !lp_winbind_enable_local_accounts() )
return False;
if ( !name )
return False;
DEBUG(10,("winbind_create_group: %s\n", name));
ZERO_STRUCT(request);
ZERO_STRUCT(response);
if ( rid )
request.flags = WBFLAG_ALLOCATE_RID;
fstrcpy( request.data.acct_mgt.groupname, name );
result = winbindd_request( WINBINDD_CREATE_GROUP, &request, &response);
if ( rid )
*rid = response.data.rid;
return result == NSS_STATUS_SUCCESS;
}
BOOL winbind_add_user_to_group( const char *user, const char *group )
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
if ( !lp_winbind_enable_local_accounts() )
return False;
if ( !user || !group )
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
DEBUG(10,("winbind_add_user_to_group: user(%s), group(%s) \n",
user, group));
fstrcpy( request.data.acct_mgt.username, user );
fstrcpy( request.data.acct_mgt.groupname, group );
result = winbindd_request( WINBINDD_ADD_USER_TO_GROUP, &request, &response);
return result == NSS_STATUS_SUCCESS;
}
BOOL winbind_remove_user_from_group( const char *user, const char *group )
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
if ( !lp_winbind_enable_local_accounts() )
return False;
if ( !user || !group )
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
DEBUG(10,("winbind_remove_user_from_group: user(%s), group(%s) \n",
user, group));
ZERO_STRUCT(response);
fstrcpy( request.data.acct_mgt.username, user );
fstrcpy( request.data.acct_mgt.groupname, group );
result = winbindd_request( WINBINDD_REMOVE_USER_FROM_GROUP, &request, &response);
return result == NSS_STATUS_SUCCESS;
}
BOOL winbind_set_user_primary_group( const char *user, const char *group )
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
if ( !lp_winbind_enable_local_accounts() )
return False;
if ( !user || !group )
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
DEBUG(10,("winbind_set_user_primary_group: user(%s), group(%s) \n",
user, group));
fstrcpy( request.data.acct_mgt.username, user );
fstrcpy( request.data.acct_mgt.groupname, group );
result = winbindd_request( WINBINDD_SET_USER_PRIMARY_GROUP, &request, &response);
return result == NSS_STATUS_SUCCESS;
}
BOOL winbind_delete_user( const char *user )
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
if ( !lp_winbind_enable_local_accounts() )
return False;
if ( !user )
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
DEBUG(10,("winbind_delete_user: user (%s)\n", user));
fstrcpy( request.data.acct_mgt.username, user );
result = winbindd_request( WINBINDD_DELETE_USER, &request, &response);
return result == NSS_STATUS_SUCCESS;
}
BOOL winbind_delete_group( const char *group )
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
if ( !lp_winbind_enable_local_accounts() )
return False;
if ( !group )
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
DEBUG(10,("winbind_delete_group: group (%s)\n", group));
fstrcpy( request.data.acct_mgt.groupname, group );
result = winbindd_request( WINBINDD_DELETE_GROUP, &request, &response);
return result == NSS_STATUS_SUCCESS;
}
#if 0
BOOL winbind_sid_to_uid_query(uid_t *puid, const DOM_SID *sid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
fstring sid_str;
if (!puid)
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
sid_to_string(sid_str, sid);
fstrcpy(request.data.sid, sid_str);
request.flags = WBFLAG_QUERY_ONLY;
result = winbindd_request(WINBINDD_SID_TO_UID, &request, &response);
if (result == NSS_STATUS_SUCCESS) {
*puid = response.data.uid;
}
return (result == NSS_STATUS_SUCCESS);
}
BOOL winbind_sid_to_gid_query(gid_t *pgid, const DOM_SID *sid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
fstring sid_str;
if (!pgid)
return False;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
sid_to_string(sid_str, sid);
fstrcpy(request.data.sid, sid_str);
request.flags = WBFLAG_QUERY_ONLY;
result = winbindd_request(WINBINDD_SID_TO_GID, &request, &response);
if (result == NSS_STATUS_SUCCESS) {
*pgid = response.data.gid;
}
return (result == NSS_STATUS_SUCCESS);
}
#endif