mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
and so it begins....
* remove idmap_XX_to_XX calls from smbd. Move back to the the winbind_XXX and local_XXX calls used in 2.2 * all uid/gid allocation must involve winbindd now * move flags field around in winbindd_request struct * add WBFLAG_QUERY_ONLY option to winbindd_sid_to_[ug]id() to prevent automatic allocation for unknown SIDs * add 'winbind trusted domains only' parameter to force a domain member server to use matching users names from /etc/passwd for its domain (needed for domain member of a Samba domain) * rename 'idmap only' to 'enable rid algorithm' for better clarity (defaults to "yes") code has been tested on * domain member of native mode 2k domain * ads domain member of native mode 2k domain * domain member of NT4 domain * domain member of Samba domain * Samba PDC running winbindd with trusts Logons tested using 2k clients and smbclient as domain users and trusted users. Tested both 'winbind trusted domains only = [yes|no]' This will be a long week of changes. The next item on the list is winbindd_passdb.c & machine trust accounts not in /etc/passwd (done via winbindd_passdb) (This used to be commit 8266dffab4aedba12a33289ff32880037ce950a8)
This commit is contained in:
parent
b5cd4a8643
commit
0b18acb841
@ -923,12 +923,8 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
|
||||
DOM_SID user_sid;
|
||||
DOM_SID group_sid;
|
||||
|
||||
struct passwd *passwd;
|
||||
|
||||
unid_t u_id, g_id;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int u_type, g_type;
|
||||
|
||||
int n_lgroupSIDs;
|
||||
DOM_SID *lgroupSIDs = NULL;
|
||||
@ -964,44 +960,20 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
|
||||
/* If the server didn't give us one, just use the one we sent them */
|
||||
domain = domain;
|
||||
}
|
||||
|
||||
/* try to fill the same account.. If getpwnam() fails, then try the
|
||||
add user script (2.2.x behavior) */
|
||||
|
||||
nt_status = fill_sam_account(mem_ctx, nt_domain, internal_username,
|
||||
&found_username, &uid, &gid, &sam_account);
|
||||
|
||||
u_type = ID_USERID;
|
||||
g_type = ID_GROUPID;
|
||||
|
||||
/* we are trying to check that idmap isn't stuffing us over - does this
|
||||
user actually exist? */
|
||||
if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&u_id, &u_type, &user_sid))
|
||||
&& NT_STATUS_IS_OK(idmap_get_id_from_sid(&g_id, &g_type, &group_sid))
|
||||
&& ((passwd = getpwuid_alloc(u_id.uid)))) {
|
||||
|
||||
nt_status = pdb_init_sam_pw(&sam_account, passwd);
|
||||
|
||||
uid = passwd->pw_uid;
|
||||
gid = passwd->pw_gid;
|
||||
|
||||
/* we should check this is the same name */
|
||||
found_username = talloc_strdup(mem_ctx, passwd->pw_name);
|
||||
|
||||
passwd_free(&passwd);
|
||||
} else {
|
||||
|
||||
/* User not from winbind - try and find them by getpwnam() */
|
||||
nt_status = fill_sam_account(mem_ctx, nt_domain,
|
||||
internal_username,
|
||||
&found_username,
|
||||
&uid, &gid,
|
||||
&sam_account);
|
||||
|
||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
|
||||
DEBUG(3,("User %s does not exist, trying to add it\n",
|
||||
internal_username));
|
||||
auth_add_user_script(nt_domain, internal_username);
|
||||
nt_status = fill_sam_account(mem_ctx, nt_domain,
|
||||
internal_username,
|
||||
&found_username,
|
||||
&uid, &gid,
|
||||
&sam_account);
|
||||
}
|
||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
|
||||
DEBUG(3,("User %s does not exist, trying to add it\n",
|
||||
internal_username));
|
||||
auth_add_user_script(nt_domain, internal_username);
|
||||
nt_status = fill_sam_account(mem_ctx, nt_domain,
|
||||
internal_username, &found_username,
|
||||
&uid, &gid, &sam_account);
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
@ -1082,12 +1054,9 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
|
||||
/* Store the user group information in the server_info
|
||||
returned to the caller. */
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status
|
||||
= get_user_groups_from_local_sam((*server_info)->unix_name,
|
||||
uid, gid,
|
||||
&n_lgroupSIDs,
|
||||
&lgroupSIDs,
|
||||
&unix_groups)))
|
||||
nt_status = get_user_groups_from_local_sam((*server_info)->unix_name,
|
||||
uid, gid, &n_lgroupSIDs, &lgroupSIDs, &unix_groups);
|
||||
if ( !NT_STATUS_IS_OK(nt_status) )
|
||||
{
|
||||
DEBUG(4,("get_user_groups_from_local_sam failed\n"));
|
||||
return nt_status;
|
||||
|
@ -85,7 +85,7 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
request.data.auth_crap.flags = WINBIND_PAM_INFO3_NDR;
|
||||
request.flags = WBFLAG_PAM_INFO3_NDR;
|
||||
|
||||
push_utf8_fstring(request.data.auth_crap.user,
|
||||
user_info->smb_name.str);
|
||||
|
@ -252,7 +252,6 @@ copy an IP address from one buffer to another
|
||||
Check to see if we are a DO for this domain
|
||||
*****************************************************************************/
|
||||
|
||||
#define IS_DC_FOR_DOMAIN(x) ( (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC) \
|
||||
&& strequal((x), lp_workgroup()) )
|
||||
#define IS_DC (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC)
|
||||
|
||||
#endif /* _SMB_MACROS_H */
|
||||
|
@ -815,7 +815,7 @@ static int smbldap_open(struct smbldap_state *ldap_state)
|
||||
}
|
||||
|
||||
if (ldap_state->ldap_struct != NULL) {
|
||||
DEBUG(5,("smbldap_open: already connected to the LDAP server\n"));
|
||||
DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
|
||||
|
||||
/* see if we should disable winbindd lookups for local users */
|
||||
if ( (p = strchr(user, *lp_winbind_separator())) == NULL ) {
|
||||
if ( setenv(WINBINDD_DONT_ENV, "1", 1) == -1 )
|
||||
if ( !winbind_off() )
|
||||
DEBUG(0,("sys_getgroup_list: Insufficient environment space for %s\n",
|
||||
WINBINDD_DONT_ENV));
|
||||
else
|
||||
@ -131,7 +131,7 @@ int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
|
||||
#endif
|
||||
|
||||
/* allow winbindd lookups */
|
||||
setenv( WINBINDD_DONT_ENV, "0", 1);
|
||||
winbind_on();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -168,6 +168,41 @@ BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
|
||||
return (result == NSS_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* Call winbindd to convert SID to uid. Do not allocate */
|
||||
|
||||
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;
|
||||
|
||||
/* Initialise request */
|
||||
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
sid_to_string(sid_str, sid);
|
||||
fstrcpy(request.data.sid, sid_str);
|
||||
|
||||
request.flags = WBFLAG_QUERY_ONLY;
|
||||
|
||||
/* Make request */
|
||||
|
||||
result = winbindd_request(WINBINDD_SID_TO_UID, &request, &response);
|
||||
|
||||
/* Copy out result */
|
||||
|
||||
if (result == NSS_STATUS_SUCCESS) {
|
||||
*puid = response.data.uid;
|
||||
}
|
||||
|
||||
return (result == NSS_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* Call winbindd to convert SID to gid */
|
||||
|
||||
BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
|
||||
@ -201,6 +236,41 @@ BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
|
||||
return (result == NSS_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* Call winbindd to convert SID to gid. Do not allocate */
|
||||
|
||||
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;
|
||||
|
||||
/* Initialise request */
|
||||
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
sid_to_string(sid_str, sid);
|
||||
fstrcpy(request.data.sid, sid_str);
|
||||
|
||||
request.flags = WBFLAG_QUERY_ONLY;
|
||||
|
||||
/* Make request */
|
||||
|
||||
result = winbindd_request(WINBINDD_SID_TO_GID, &request, &response);
|
||||
|
||||
/* Copy out result */
|
||||
|
||||
if (result == NSS_STATUS_SUCCESS) {
|
||||
*pgid = response.data.gid;
|
||||
}
|
||||
|
||||
return (result == NSS_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* Call winbindd to convert gid to sid */
|
||||
|
||||
BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
|
||||
|
@ -468,3 +468,19 @@ NSS_STATUS winbindd_request(int req_type,
|
||||
return(status);
|
||||
return winbindd_get_response(response);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
A couple of simple jfunctions to disable winbindd lookups and re-
|
||||
enable them
|
||||
************************************************************************/
|
||||
|
||||
BOOL winbind_off( void )
|
||||
{
|
||||
return (setenv( WINBINDD_DONT_ENV, "1", 1 ) != -1);
|
||||
}
|
||||
|
||||
BOOL winbind_on( void )
|
||||
{
|
||||
return (setenv( WINBINDD_DONT_ENV, "0", 1 ) != -1);
|
||||
}
|
||||
|
||||
|
@ -214,10 +214,11 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
|
||||
if (!parse_domain_user(tmp, name_domain, name_group))
|
||||
return WINBINDD_ERROR;
|
||||
|
||||
/* don't handle our own domain if we are a DC. This code handles cases where
|
||||
/* don't handle our own domain if we are a DC ( or a member of a Samba domain
|
||||
that shares UNIX accounts). This code handles cases where
|
||||
the account doesn't exist anywhere and gets passed on down the NSS layer */
|
||||
|
||||
if ( IS_DC_FOR_DOMAIN(domain->name) ) {
|
||||
if ( (IS_DC || lp_winbind_trusted_domains_only()) && strequal(name_domain, lp_workgroup()) ) {
|
||||
DEBUG(7,("winbindd_getgrnam: rejecting getpwnam() for %s\\%s since I am on the PDC for this domain\n",
|
||||
name_domain, name_group));
|
||||
return WINBINDD_ERROR;
|
||||
@ -248,7 +249,7 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid))) {
|
||||
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &gid, 0))) {
|
||||
DEBUG(1, ("error converting unix gid to sid\n"));
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
@ -293,7 +294,7 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
|
||||
return WINBINDD_ERROR;
|
||||
|
||||
/* Get rid from gid */
|
||||
if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, state->request.data.gid))) {
|
||||
if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&group_sid, state->request.data.gid))) {
|
||||
DEBUG(1, ("could not convert gid %d to rid\n",
|
||||
state->request.data.gid));
|
||||
return WINBINDD_ERROR;
|
||||
@ -370,10 +371,14 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
|
||||
struct getent_state *domain_state;
|
||||
|
||||
|
||||
/* don't add our domaina if we are a PDC */
|
||||
/* don't add our domaina if we are a PDC or if we
|
||||
are a member of a Samba domain */
|
||||
|
||||
if ( IS_DC_FOR_DOMAIN(domain->name) )
|
||||
if ( (IS_DC || lp_winbind_trusted_domains_only())
|
||||
&& strequal(domain->name, lp_workgroup()) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create a state record for this domain */
|
||||
|
||||
@ -612,7 +617,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
|
||||
sid_copy(&group_sid, &domain->sid);
|
||||
sid_append_rid(&group_sid, name_list[ent->sam_entry_index].rid);
|
||||
|
||||
if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &group_gid))) {
|
||||
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &group_gid, 0))) {
|
||||
|
||||
DEBUG(1, ("could not look up gid for group %s\n",
|
||||
name_list[ent->sam_entry_index].acct_name));
|
||||
@ -925,8 +930,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
|
||||
|
||||
/* Map to a gid */
|
||||
|
||||
if (!NT_STATUS_IS_OK(sid_to_gid(&info3->other_sids[i].sid,
|
||||
&gid_list[num_gids])) )
|
||||
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&info3->other_sids[i].sid, &gid_list[num_gids], 0)) )
|
||||
{
|
||||
DEBUG(10, ("winbindd_getgroups: could not map sid %s to gid\n",
|
||||
sid_string_static(&info3->other_sids[i].sid)));
|
||||
@ -950,7 +954,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
|
||||
sid_copy( &group_sid, &domain->sid );
|
||||
sid_append_rid( &group_sid, info3->gids[i].g_rid );
|
||||
|
||||
if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid_list[num_gids])) ) {
|
||||
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &gid_list[num_gids], 0)) ) {
|
||||
DEBUG(10, ("winbindd_getgroups: could not map sid %s to gid\n",
|
||||
sid_string_static(&group_sid)));
|
||||
}
|
||||
@ -973,7 +977,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < num_groups; i++) {
|
||||
if (!NT_STATUS_IS_OK(sid_to_gid(user_grpsids[i], &gid_list[num_gids]))) {
|
||||
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(user_grpsids[i], &gid_list[num_gids], 0))) {
|
||||
DEBUG(1, ("unable to convert group sid %s to gid\n",
|
||||
sid_string_static(user_grpsids[i])));
|
||||
continue;
|
||||
|
@ -111,11 +111,12 @@ enum winbindd_cmd {
|
||||
WINBINDD_NUM_CMDS
|
||||
};
|
||||
|
||||
#define WINBIND_PAM_INFO3_NDR 0x0001
|
||||
#define WINBIND_PAM_INFO3_TEXT 0x0002
|
||||
#define WINBIND_PAM_NTKEY 0x0004
|
||||
#define WINBIND_PAM_LMKEY 0x0008
|
||||
#define WINBIND_PAM_CONTACT_TRUSTDOM 0x0010
|
||||
#define WBFLAG_PAM_INFO3_NDR 0x0001
|
||||
#define WBFLAG_PAM_INFO3_TEXT 0x0002
|
||||
#define WBFLAG_PAM_NTKEY 0x0004
|
||||
#define WBFLAG_PAM_LMKEY 0x0008
|
||||
#define WBFLAG_PAM_CONTACT_TRUSTDOM 0x0010
|
||||
#define WBFLAG_QUERY_ONLY 0x0020
|
||||
|
||||
/* Winbind request structure */
|
||||
|
||||
@ -123,6 +124,7 @@ struct winbindd_request {
|
||||
uint32 length;
|
||||
enum winbindd_cmd cmd; /* Winbindd command to execute */
|
||||
pid_t pid; /* pid of calling process */
|
||||
uint32 flags; /* flags relavant to a given request */
|
||||
|
||||
union {
|
||||
fstring winsreq; /* WINS request */
|
||||
@ -146,7 +148,6 @@ struct winbindd_request {
|
||||
fstring nt_resp;
|
||||
uint16 nt_resp_len;
|
||||
fstring workstation;
|
||||
uint32 flags;
|
||||
} auth_crap;
|
||||
struct {
|
||||
fstring user;
|
||||
|
@ -63,29 +63,11 @@ static BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16],
|
||||
DOM_SID sid;
|
||||
char *pwd;
|
||||
|
||||
if ( lp_server_role()==ROLE_DOMAIN_MEMBER || strequal(domain, lp_workgroup()) )
|
||||
/* if we are a DC and this is not our domain, then lookup an account
|
||||
for the domain trust */
|
||||
|
||||
if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() )
|
||||
{
|
||||
/*
|
||||
* Get the machine account password for the domain to contact.
|
||||
* This is either our own domain for a workstation, or possibly
|
||||
* any domain for a PDC with trusted domains.
|
||||
*/
|
||||
|
||||
if ( !secrets_fetch_trust_account_password (domain, ret_pwd,
|
||||
pass_last_set_time, channel) )
|
||||
{
|
||||
DEBUG(0, ("get_trust_pw: could not fetch trust account "
|
||||
"password for my domain %s\n", domain));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
else if ( lp_allow_trusted_domains() )
|
||||
{
|
||||
/* if we are not a domain member, then we must be a DC and
|
||||
this must be a trusted domain */
|
||||
|
||||
if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
|
||||
pass_last_set_time) )
|
||||
{
|
||||
@ -100,6 +82,21 @@ static BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16],
|
||||
|
||||
return True;
|
||||
}
|
||||
else /* just get the account for our domain (covers
|
||||
ROLE_DOMAIN_MEMBER as well */
|
||||
{
|
||||
/* get the machine trust account for our domain */
|
||||
|
||||
if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd,
|
||||
pass_last_set_time, channel) )
|
||||
{
|
||||
DEBUG(0, ("get_trust_pw: could not fetch trust account "
|
||||
"password for my domain %s\n", domain));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Failure */
|
||||
return False;
|
||||
@ -126,6 +123,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
int attempts = 0;
|
||||
unsigned char local_lm_response[24];
|
||||
unsigned char local_nt_response[24];
|
||||
const char *contact_domain;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
|
||||
@ -166,6 +164,13 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* what domain should we contact? */
|
||||
|
||||
if ( IS_DC )
|
||||
contact_domain = name_domain;
|
||||
else
|
||||
contact_domain = lp_workgroup();
|
||||
|
||||
/* check authentication loop */
|
||||
|
||||
do {
|
||||
@ -173,7 +178,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
ZERO_STRUCT(ret_creds);
|
||||
|
||||
/* Don't shut this down - it belongs to the connection cache code */
|
||||
result = cm_get_netlogon_cli(name_domain, trust_passwd,
|
||||
result = cm_get_netlogon_cli(contact_domain, trust_passwd,
|
||||
sec_channel_type, False, &cli);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
@ -255,6 +260,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
char *user = NULL;
|
||||
const char *domain = NULL;
|
||||
const char *workstation;
|
||||
const char *contact_domain;
|
||||
DOM_CRED ret_creds;
|
||||
int attempts = 0;
|
||||
|
||||
@ -329,12 +335,19 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
lm_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len);
|
||||
nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len);
|
||||
|
||||
/* what domain should we contact? */
|
||||
|
||||
if ( IS_DC )
|
||||
contact_domain = domain;
|
||||
else
|
||||
contact_domain = lp_workgroup();
|
||||
|
||||
do {
|
||||
ZERO_STRUCT(info3);
|
||||
ZERO_STRUCT(ret_creds);
|
||||
|
||||
/* Don't shut this down - it belongs to the connection cache code */
|
||||
result = cm_get_netlogon_cli(domain, trust_passwd, sec_channel_type, False, &cli);
|
||||
result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, False, &cli);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n",
|
||||
@ -376,14 +389,14 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
netsamlogon_cache_store( cli->mem_ctx, &info3 );
|
||||
wcache_invalidate_samlogon(find_domain_from_name(domain), &info3);
|
||||
|
||||
if (state->request.data.auth_crap.flags & WINBIND_PAM_INFO3_NDR) {
|
||||
if (state->request.flags & WBFLAG_PAM_INFO3_NDR) {
|
||||
result = append_info3_as_ndr(mem_ctx, state, &info3);
|
||||
}
|
||||
|
||||
if (state->request.data.auth_crap.flags & WINBIND_PAM_NTKEY) {
|
||||
if (state->request.flags & WBFLAG_PAM_NTKEY) {
|
||||
memcpy(state->response.data.auth.nt_session_key, info3.user_sess_key, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
|
||||
}
|
||||
if (state->request.data.auth_crap.flags & WINBIND_PAM_LMKEY) {
|
||||
if (state->request.flags & WBFLAG_PAM_LMKEY) {
|
||||
memcpy(state->response.data.auth.first_8_lm_hash, info3.padding, sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */);
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
|
||||
DEBUG(3,("pdb: sid_to_name sid=%s\n", sid_string_static(sid)));
|
||||
|
||||
if (NT_STATUS_IS_OK(sid_to_uid(sid, &id))) { /* this is a user */
|
||||
if (NT_STATUS_IS_OK(idmap_sid_to_uid(sid, &id, 0))) { /* this is a user */
|
||||
|
||||
if (!NT_STATUS_IS_OK(result = pdb_init_sam(&sam_account))) {
|
||||
return result;
|
||||
@ -197,7 +197,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
*type = SID_NAME_USER;
|
||||
result = NT_STATUS_OK;
|
||||
|
||||
} else if (NT_STATUS_IS_OK(sid_to_gid(sid, &id))) { /* this is a group */
|
||||
} else if (NT_STATUS_IS_OK(idmap_sid_to_gid(sid, &id, 0))) { /* this is a group */
|
||||
|
||||
DEBUG(3,("pdb: sid_to_name: group support not implemented\n"));
|
||||
result = NT_STATUS_UNSUCCESSFUL;
|
||||
|
@ -122,6 +122,7 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
|
||||
enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
|
||||
{
|
||||
DOM_SID sid;
|
||||
uint32 flags = 0x0;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
|
||||
@ -131,15 +132,16 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
|
||||
|
||||
/* Split sid into domain sid and user rid */
|
||||
if (!string_to_sid(&sid, state->request.data.sid)) {
|
||||
DEBUG(1, ("Could not get convert sid %s from string\n",
|
||||
state->request.data.sid));
|
||||
DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid));
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if ( state->request.flags & WBFLAG_QUERY_ONLY )
|
||||
flags = ID_QUERY_ONLY;
|
||||
|
||||
/* Find uid for this sid and return it */
|
||||
if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &(state->response.data.uid)))) {
|
||||
DEBUG(1, ("Could not get uid for sid %s\n",
|
||||
state->request.data.sid));
|
||||
if ( !NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) ) {
|
||||
DEBUG(1, ("Could not get uid for sid %s\n", state->request.data.sid));
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
|
||||
@ -152,6 +154,7 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
|
||||
enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
|
||||
{
|
||||
DOM_SID sid;
|
||||
uint32 flags = 0x0;
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
|
||||
@ -160,15 +163,16 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
|
||||
state->request.data.sid));
|
||||
|
||||
if (!string_to_sid(&sid, state->request.data.sid)) {
|
||||
DEBUG(1, ("Could not cvt string to sid %s\n",
|
||||
state->request.data.sid));
|
||||
DEBUG(1, ("Could not cvt string to sid %s\n", state->request.data.sid));
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
|
||||
if ( state->request.flags & WBFLAG_QUERY_ONLY )
|
||||
flags = ID_QUERY_ONLY;
|
||||
|
||||
/* Find gid for this sid and return it */
|
||||
if (!NT_STATUS_IS_OK(sid_to_gid(&sid, &(state->response.data.gid)))) {
|
||||
DEBUG(1, ("Could not get gid for sid %s\n",
|
||||
state->request.data.sid));
|
||||
if ( !NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) ) {
|
||||
DEBUG(1, ("Could not get gid for sid %s\n", state->request.data.sid));
|
||||
return WINBINDD_ERROR;
|
||||
}
|
||||
|
||||
@ -192,7 +196,7 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state)
|
||||
state->request.data.uid));
|
||||
|
||||
/* Lookup rid for this uid */
|
||||
if (!NT_STATUS_IS_OK(uid_to_sid(&sid, state->request.data.uid))) {
|
||||
if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid))) {
|
||||
DEBUG(1, ("Could not convert uid %d to rid\n",
|
||||
state->request.data.uid));
|
||||
return WINBINDD_ERROR;
|
||||
@ -221,7 +225,7 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state)
|
||||
state->request.data.gid));
|
||||
|
||||
/* Lookup sid for this uid */
|
||||
if (!NT_STATUS_IS_OK(gid_to_sid(&sid, state->request.data.gid))) {
|
||||
if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid))) {
|
||||
DEBUG(1, ("Could not convert gid %d to sid\n",
|
||||
state->request.data.gid));
|
||||
return WINBINDD_ERROR;
|
||||
|
@ -44,14 +44,14 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
|
||||
|
||||
/* Resolve the uid number */
|
||||
|
||||
if (!NT_STATUS_IS_OK(sid_to_uid(user_sid, &(pw->pw_uid)))) {
|
||||
if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &(pw->pw_uid), 0))) {
|
||||
DEBUG(1, ("error getting user id for sid %s\n", sid_to_string(sid_string, user_sid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Resolve the gid number */
|
||||
|
||||
if (!NT_STATUS_IS_OK(sid_to_gid(group_sid, &(pw->pw_gid)))) {
|
||||
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &(pw->pw_gid), 0))) {
|
||||
DEBUG(1, ("error getting group id for sid %s\n", sid_to_string(sid_string, group_sid)));
|
||||
return False;
|
||||
}
|
||||
@ -116,10 +116,11 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
|
||||
name_user))
|
||||
return WINBINDD_ERROR;
|
||||
|
||||
/* don't handle our own domain if we are a DC. This code handles cases where
|
||||
/* don't handle our own domain if we are a DC ( or a member of a Samba domain
|
||||
that shares UNIX accounts). This code handles cases where
|
||||
the account doesn't exist anywhere and gets passed on down the NSS layer */
|
||||
|
||||
if ( IS_DC_FOR_DOMAIN(domain->name) ) {
|
||||
if ( (IS_DC || lp_winbind_trusted_domains_only()) && strequal(name_domain, lp_workgroup()) ) {
|
||||
DEBUG(7,("winbindd_getpwnam: rejecting getpwnam() for %s\\%s since I am on the PDC for this domain\n",
|
||||
name_domain, name_user));
|
||||
return WINBINDD_ERROR;
|
||||
@ -202,7 +203,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
|
||||
|
||||
/* Get rid from uid */
|
||||
|
||||
if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, state->request.data.uid))) {
|
||||
if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&user_sid, state->request.data.uid))) {
|
||||
DEBUG(1, ("could not convert uid %d to SID\n",
|
||||
state->request.data.uid));
|
||||
return WINBINDD_ERROR;
|
||||
@ -246,7 +247,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
|
||||
|
||||
/* Check group has a gid number */
|
||||
|
||||
if (!NT_STATUS_IS_OK(sid_to_gid(user_info.group_sid, &gid))) {
|
||||
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(user_info.group_sid, &gid, 0))) {
|
||||
DEBUG(1, ("error getting group id for user %s\n", user_name));
|
||||
talloc_destroy(mem_ctx);
|
||||
return WINBINDD_ERROR;
|
||||
@ -296,10 +297,14 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
|
||||
struct getent_state *domain_state;
|
||||
|
||||
|
||||
/* don't add our domaina if we are a PDC */
|
||||
/* don't add our domaina if we are a PDC or if we
|
||||
are a member of a Samba domain */
|
||||
|
||||
if ( IS_DC_FOR_DOMAIN( domain->name ) )
|
||||
continue;
|
||||
if ( (IS_DC || lp_winbind_trusted_domains_only())
|
||||
&& strequal(domain->name, lp_workgroup()) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create a state record for this domain */
|
||||
|
||||
|
@ -163,8 +163,7 @@ typedef struct
|
||||
char *szSourceEnv;
|
||||
char *szIdmapUID;
|
||||
char *szIdmapGID;
|
||||
BOOL *bIdmapOnly;
|
||||
char *szNonUnixAccountRange;
|
||||
BOOL bEnableRidAlgorithm;
|
||||
int AlgorithmicRidBase;
|
||||
char *szTemplateHomedir;
|
||||
char *szTemplateShell;
|
||||
@ -172,6 +171,7 @@ typedef struct
|
||||
BOOL bWinbindEnumUsers;
|
||||
BOOL bWinbindEnumGroups;
|
||||
BOOL bWinbindUseDefaultDomain;
|
||||
BOOL bWinbindTrustedDomainsOnly;
|
||||
char *szWinbindBackend;
|
||||
char *szIdmapBackend;
|
||||
char *szAddShareCommand;
|
||||
@ -1117,7 +1117,7 @@ static struct parm_struct parm_table[] = {
|
||||
|
||||
{"Winbind options", P_SEP, P_SEPARATOR},
|
||||
|
||||
{"idmap only", P_BOOL, P_GLOBAL, &Globals.bIdmapOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
{"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_DEPRECATED},
|
||||
{"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
{"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
{"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_DEPRECATED },
|
||||
@ -1130,6 +1130,7 @@ static struct parm_struct parm_table[] = {
|
||||
{"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
{"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
{"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
{"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
|
||||
{NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
|
||||
};
|
||||
@ -1467,12 +1468,13 @@ static void init_globals(void)
|
||||
string_set(&Globals.szWinbindSeparator, "\\");
|
||||
string_set(&Globals.szAclCompat, "");
|
||||
|
||||
Globals.winbind_cache_time = 600; /* 5 minutes */
|
||||
Globals.winbind_cache_time = 300; /* 5 minutes */
|
||||
Globals.bWinbindEnumUsers = True;
|
||||
Globals.bWinbindEnumGroups = True;
|
||||
Globals.bWinbindUseDefaultDomain = False;
|
||||
Globals.bWinbindTrustedDomainsOnly = False;
|
||||
|
||||
Globals.bIdmapOnly = False;
|
||||
Globals.bEnableRidAlgorithm = True;
|
||||
|
||||
Globals.name_cache_timeout = 660; /* In seconds */
|
||||
|
||||
@ -1637,9 +1639,10 @@ FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat)
|
||||
FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
|
||||
FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
|
||||
FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
|
||||
FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
|
||||
|
||||
FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
|
||||
FN_GLOBAL_BOOL(lp_idmap_only, &Globals.bIdmapOnly)
|
||||
FN_GLOBAL_BOOL(lp_enable_rid_algorithm, &Globals.bEnableRidAlgorithm)
|
||||
|
||||
#ifdef WITH_LDAP_SAMCONFIG
|
||||
FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
|
||||
|
@ -892,10 +892,6 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
|
||||
|
||||
/*************************************************************
|
||||
Change a password entry in the local smbpasswd file.
|
||||
|
||||
It is currently being called by SWAT and by smbpasswd.
|
||||
|
||||
--jerry
|
||||
*************************************************************/
|
||||
|
||||
BOOL local_password_change(const char *user_name, int local_flags,
|
||||
@ -1040,3 +1036,201 @@ BOOL local_password_change(const char *user_name, int local_flags,
|
||||
pdb_free_sam(&sam_pass);
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Convert a uid to SID - locally.
|
||||
****************************************************************************/
|
||||
|
||||
DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
|
||||
{
|
||||
SAM_ACCOUNT *sampw = NULL;
|
||||
struct passwd *unix_pw;
|
||||
|
||||
|
||||
|
||||
winbind_off();
|
||||
unix_pw = sys_getpwuid( uid );
|
||||
winbind_on();
|
||||
|
||||
if ( !unix_pw ) {
|
||||
DEBUG(4,("local_uid_to_sid: host has know idea of uid %d\n", uid));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
|
||||
DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUTN object\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !pdb_getsampwnam( sampw, unix_pw->pw_name ) ) {
|
||||
DEBUG(4,("local_uid_to_sid: User %s [uid == %d] has no samba account\n",
|
||||
unix_pw->pw_name, uid));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sid_copy( psid, pdb_get_user_sid(sampw) );
|
||||
|
||||
DEBUG(10,("local_uid_to_sid: uid (%d) -> SID %s (%s).\n",
|
||||
(unsigned int)uid, sid_string_static(psid), unix_pw->pw_name));
|
||||
|
||||
return psid;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Convert a SID to uid - locally.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
||||
{
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
SAM_ACCOUNT *sampw = NULL;
|
||||
struct passwd *unix_pw;
|
||||
const char *user_name;
|
||||
|
||||
*name_type = SID_NAME_UNKNOWN;
|
||||
|
||||
sid_copy(&dom_sid, psid);
|
||||
sid_split_rid(&dom_sid, &rid);
|
||||
|
||||
/*
|
||||
* We can only convert to a uid if this is our local
|
||||
* Domain SID (ie. we are the controling authority).
|
||||
*/
|
||||
if ( !sid_equal(get_global_sam_sid(), &dom_sid) )
|
||||
return False;
|
||||
|
||||
|
||||
/* lookup the user account */
|
||||
|
||||
if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
|
||||
DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( !pdb_getsampwsid(sampw, psid) ) {
|
||||
DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n",
|
||||
sid_string_static(psid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
user_name = pdb_get_username(sampw);
|
||||
|
||||
winbind_off();
|
||||
unix_pw = sys_getpwnam( user_name );
|
||||
winbind_on();
|
||||
|
||||
if ( !unix_pw ) {
|
||||
DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n",
|
||||
user_name));
|
||||
pdb_free_sam( &sampw );
|
||||
return False;
|
||||
}
|
||||
|
||||
*puid = unix_pw->pw_uid;
|
||||
|
||||
DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid),
|
||||
(unsigned int)*puid, user_name ));
|
||||
|
||||
*name_type = SID_NAME_USER;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Convert a gid to SID - locally.
|
||||
****************************************************************************/
|
||||
|
||||
DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
|
||||
{
|
||||
GROUP_MAP group;
|
||||
|
||||
/* we don't need to disable winbindd since the gid is stored in
|
||||
the GROUP_MAP object */
|
||||
|
||||
if ( !pdb_getgrgid( &group, gid ) ) {
|
||||
|
||||
/* fallback to rid mapping if enabled */
|
||||
|
||||
if ( lp_enable_rid_algorithm() ) {
|
||||
sid_copy(psid, get_global_sam_sid());
|
||||
sid_append_rid(psid, pdb_gid_to_group_rid(gid));
|
||||
|
||||
DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n",
|
||||
(unsigned int)gid, sid_string_static(psid)));
|
||||
|
||||
return psid;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sid_copy( psid, &group.sid );
|
||||
|
||||
DEBUG(10,("local_gid_to_sid: gid (%d) -> SID %s.\n",
|
||||
(unsigned int)gid, sid_string_static(psid)));
|
||||
|
||||
return psid;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Convert a SID to gid - locally.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
|
||||
{
|
||||
DOM_SID dom_sid;
|
||||
uint32 rid;
|
||||
GROUP_MAP group;
|
||||
|
||||
*name_type = SID_NAME_UNKNOWN;
|
||||
|
||||
/* This call can enumerate grou mappings for foreign sids as well.
|
||||
So don't check for a match against our domain SID */
|
||||
|
||||
/* we don't need to disable winbindd since the gid is stored in
|
||||
the GROUP_MAP object */
|
||||
|
||||
if ( !pdb_getgrsid(&group, *psid) ) {
|
||||
|
||||
/* fallback to rid mapping if enabled */
|
||||
|
||||
if ( lp_enable_rid_algorithm() ) {
|
||||
sid_copy(&dom_sid, psid);
|
||||
sid_split_rid(&dom_sid, &rid);
|
||||
|
||||
if (!sid_equal(get_global_sam_sid(), &dom_sid) ) {
|
||||
DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (not %s)\n",
|
||||
sid_string_static(&dom_sid)));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!sid_peek_rid(psid, &rid)) {
|
||||
DEBUG(10,("local_sid_to_uid: invalid SID!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n"));
|
||||
|
||||
if (fallback_pdb_rid_is_user(rid)) {
|
||||
DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid)));
|
||||
return False;
|
||||
} else {
|
||||
*pgid = pdb_group_rid_to_gid(rid);
|
||||
DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid)));
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
*pgid = group.gid;
|
||||
|
||||
DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid),
|
||||
(unsigned int)*pgid));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2217,7 +2217,7 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
|
||||
count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
|
||||
|
||||
if (count < 1) {
|
||||
DEBUG(4, ("Did not find group for filter %s\n", filter));
|
||||
DEBUG(4, ("Did not find group\n"));
|
||||
return NT_STATUS_NO_SUCH_GROUP;
|
||||
}
|
||||
|
||||
@ -2327,6 +2327,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
|
||||
(struct ldapsam_privates *)methods->private_data;
|
||||
LDAPMessage *result = NULL;
|
||||
LDAPMod **mods = NULL;
|
||||
int count;
|
||||
|
||||
char *tmp;
|
||||
pstring dn;
|
||||
@ -2347,7 +2348,12 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 1) {
|
||||
count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
|
||||
|
||||
if ( count == 0 )
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
if (count > 1) {
|
||||
DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
|
||||
map->gid));
|
||||
ldap_msgfree(result);
|
||||
|
@ -93,7 +93,7 @@ BOOL idmap_get_free_rid_range(uint32 *low, uint32 *high)
|
||||
{
|
||||
uint32 id_low, id_high;
|
||||
|
||||
if (lp_idmap_only()) {
|
||||
if (!lp_enable_rid_algorithm()) {
|
||||
*low = BASE_RID;
|
||||
*high = (uint32)-1;
|
||||
}
|
||||
@ -134,130 +134,71 @@ BOOL idmap_get_free_ugid_range(uint32 *low, uint32 *high)
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*THE CANONICAL* convert uid_t to SID function.
|
||||
check idmap if uid is in idmap range, otherwise falls back to
|
||||
the legacy algorithmic mapping.
|
||||
Returns SID pointer.
|
||||
the legacy algorithmic mapping. Returns SID pointer.
|
||||
*****************************************************************/
|
||||
|
||||
NTSTATUS uid_to_sid(DOM_SID *sid, uid_t uid)
|
||||
NTSTATUS idmap_uid_to_sid(DOM_SID *sid, uid_t uid)
|
||||
{
|
||||
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
|
||||
unid_t id;
|
||||
int flags;
|
||||
|
||||
DEBUG(10,("uid_to_sid: uid = [%d]\n", uid));
|
||||
DEBUG(10,("idmap_uid_to_sid: uid = [%d]\n", uid));
|
||||
|
||||
flags = ID_USERID;
|
||||
if (!lp_idmap_only() && !idmap_check_ugid_is_in_free_range(uid)) {
|
||||
flags |= ID_QUERY_ONLY;
|
||||
}
|
||||
|
||||
id.uid = uid;
|
||||
if (!NT_STATUS_IS_OK(ret = idmap_get_sid_from_id(sid, id, flags))) {
|
||||
DEBUG(10, ("uid_to_sid: Failed to map uid = [%u]\n", (unsigned int)uid));
|
||||
if (flags & ID_QUERY_ONLY) {
|
||||
sid_copy(sid, get_global_sam_sid());
|
||||
sid_append_rid(sid, fallback_pdb_uid_to_user_rid(uid));
|
||||
|
||||
DEBUG(10,("uid_to_sid: Fall back to algorithmic mapping: %u -> %s\n", (unsigned int)uid, sid_string_static(sid)));
|
||||
ret = NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
return idmap_get_sid_from_id(sid, id, flags);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*THE CANONICAL* convert gid_t to SID function.
|
||||
check idmap if gid is in idmap range, otherwise falls back to
|
||||
the legacy algorithmic mapping.
|
||||
Group mapping is used for gids that maps to Wellknown SIDs
|
||||
Returns SID pointer.
|
||||
*****************************************************************/
|
||||
|
||||
NTSTATUS gid_to_sid(DOM_SID *sid, gid_t gid)
|
||||
NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid)
|
||||
{
|
||||
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
|
||||
unid_t id;
|
||||
int flags;
|
||||
|
||||
DEBUG(10,("gid_to_sid: gid = [%d]\n", gid));
|
||||
DEBUG(10,("idmap_gid_to_sid: gid = [%d]\n", gid));
|
||||
|
||||
flags = ID_GROUPID;
|
||||
if (!lp_idmap_only() && !idmap_check_ugid_is_in_free_range(gid)) {
|
||||
if (!idmap_check_ugid_is_in_free_range(gid)) {
|
||||
flags |= ID_QUERY_ONLY;
|
||||
}
|
||||
|
||||
id.gid = gid;
|
||||
if (!NT_STATUS_IS_OK(ret = idmap_get_sid_from_id(sid, id, flags))) {
|
||||
DEBUG(10, ("gid_to_sid: Failed to map gid = [%u]\n", (unsigned int)gid));
|
||||
if (flags & ID_QUERY_ONLY) {
|
||||
sid_copy(sid, get_global_sam_sid());
|
||||
sid_append_rid(sid, pdb_gid_to_group_rid(gid));
|
||||
|
||||
DEBUG(10,("gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n", (unsigned int)gid, sid_string_static(sid)));
|
||||
ret = NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return idmap_get_sid_from_id(sid, id, flags);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*THE CANONICAL* convert SID to uid function.
|
||||
if it is a foreign sid or it is in idmap rid range check idmap,
|
||||
otherwise falls back to the legacy algorithmic mapping.
|
||||
Returns True if this name is a user sid and the conversion
|
||||
was done correctly, False if not.
|
||||
*****************************************************************/
|
||||
|
||||
NTSTATUS sid_to_uid(const DOM_SID *sid, uid_t *uid)
|
||||
NTSTATUS idmap_sid_to_uid(const DOM_SID *sid, uid_t *uid, uint32 flags)
|
||||
{
|
||||
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
|
||||
BOOL fallback = False;
|
||||
unid_t id;
|
||||
int flags;
|
||||
|
||||
DEBUG(10,("sid_to_uid: sid = [%s]\n", sid_string_static(sid)));
|
||||
DEBUG(10,("idmap_sid_to_uid: sid = [%s]\n", sid_string_static(sid)));
|
||||
|
||||
flags = ID_USERID;
|
||||
if (!lp_idmap_only()) {
|
||||
if (!idmap_check_sid_is_in_free_range(sid)) {
|
||||
flags |= ID_QUERY_ONLY;
|
||||
fallback = True;
|
||||
}
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_OK(ret = idmap_get_id_from_sid(&id, &flags, sid))) {
|
||||
|
||||
DEBUG(10,("sid_to_uid: uid = [%d]\n", id.uid));
|
||||
flags |= ID_USERID;
|
||||
|
||||
ret = idmap_get_id_from_sid(&id, &flags, sid);
|
||||
|
||||
if ( NT_STATUS_IS_OK(ret) ) {
|
||||
DEBUG(10,("idmap_sid_to_uid: uid = [%d]\n", id.uid));
|
||||
*uid = id.uid;
|
||||
|
||||
} else if (fallback) {
|
||||
uint32 rid;
|
||||
}
|
||||
|
||||
if (!sid_peek_rid(sid, &rid)) {
|
||||
DEBUG(10,("sid_to_uid: invalid SID!\n"));
|
||||
ret = NT_STATUS_INVALID_PARAMETER;
|
||||
goto done;
|
||||
}
|
||||
|
||||
DEBUG(10,("sid_to_uid: Fall back to algorithmic mapping\n"));
|
||||
|
||||
if (!fallback_pdb_rid_is_user(rid)) {
|
||||
DEBUG(3, ("sid_to_uid: SID %s is *NOT* a user\n", sid_string_static(sid)));
|
||||
ret = NT_STATUS_UNSUCCESSFUL;
|
||||
} else {
|
||||
*uid = fallback_pdb_user_rid_to_uid(rid);
|
||||
DEBUG(10,("sid_to_uid: mapping: %s -> %u\n", sid_string_static(sid), (unsigned int)(*uid)));
|
||||
ret = NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
@ -269,51 +210,27 @@ done:
|
||||
was done correctly, False if not.
|
||||
*****************************************************************/
|
||||
|
||||
NTSTATUS sid_to_gid(const DOM_SID *sid, gid_t *gid)
|
||||
NTSTATUS idmap_sid_to_gid(const DOM_SID *sid, gid_t *gid, uint32 flags)
|
||||
{
|
||||
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
|
||||
BOOL fallback = False;
|
||||
unid_t id;
|
||||
int flags;
|
||||
|
||||
DEBUG(10,("sid_to_gid: sid = [%s]\n", sid_string_static(sid)));
|
||||
|
||||
flags = ID_GROUPID;
|
||||
if (!lp_idmap_only()) {
|
||||
if (!idmap_check_sid_is_in_free_range(sid)) {
|
||||
flags |= ID_QUERY_ONLY;
|
||||
fallback = True;
|
||||
}
|
||||
}
|
||||
flags |= ID_GROUPID;
|
||||
|
||||
if (NT_STATUS_IS_OK(ret = idmap_get_id_from_sid(&id, &flags, sid))) {
|
||||
|
||||
DEBUG(10,("sid_to_gid: gid = [%d]\n", id.gid));
|
||||
ret = idmap_get_id_from_sid(&id, &flags, sid);
|
||||
|
||||
if ( NT_STATUS_IS_OK(ret) )
|
||||
{
|
||||
DEBUG(10,("idmap_sid_to_gid: gid = [%d]\n", id.gid));
|
||||
*gid = id.gid;
|
||||
|
||||
} else if (fallback) {
|
||||
uint32 rid;
|
||||
|
||||
if (!sid_peek_rid(sid, &rid)) {
|
||||
DEBUG(10,("sid_to_uid: invalid SID!\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
DEBUG(10,("sid_to_gid: Fall back to algorithmic mapping\n"));
|
||||
|
||||
if (fallback_pdb_rid_is_user(rid)) {
|
||||
DEBUG(3, ("sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(sid)));
|
||||
ret = NT_STATUS_UNSUCCESSFUL;
|
||||
} else {
|
||||
*gid = pdb_group_rid_to_gid(rid);
|
||||
DEBUG(10,("sid_to_gid: mapping: %s -> %u\n", sid_string_static(sid), (unsigned int)(*gid)));
|
||||
ret = NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Check first, call set_mapping if it doesn't already exist.
|
||||
***************************************************************************/
|
||||
|
@ -842,7 +842,7 @@ void build_options(BOOL screen);
|
||||
if (!init_registry())
|
||||
exit(1);
|
||||
|
||||
/* Initialise the password backed before idmap and the global_sam_sid
|
||||
/* Initialise the password backed before the global_sam_sid
|
||||
to ensure that we fetch from ldap before we make a domain sid up */
|
||||
|
||||
if(!initialize_password_db(False))
|
||||
@ -855,18 +855,6 @@ void build_options(BOOL screen);
|
||||
|
||||
static_init_auth;
|
||||
|
||||
{
|
||||
const char *idmap_back = lp_idmap_backend();
|
||||
|
||||
if (!idmap_init((idmap_back && *idmap_back) ? "winbind" : NULL))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!idmap_init_wellknown_sids()) {
|
||||
DEBUG(0,("ERROR: Samba failed to initialize it's 'well known' SID -> ID mapping tables.\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static_init_rpc;
|
||||
|
||||
init_modules();
|
||||
|
@ -529,3 +529,411 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
Id mapping cache. This is to avoid Winbind mappings already
|
||||
seen by smbd to be queried too frequently, keeping winbindd
|
||||
busy, and blocking smbd while winbindd is busy with other
|
||||
stuff. Written by Michael Steffens <michael.steffens@hp.com>,
|
||||
modified to use linked lists by jra.
|
||||
*****************************************************************/
|
||||
|
||||
#define MAX_UID_SID_CACHE_SIZE 100
|
||||
#define TURNOVER_UID_SID_CACHE_SIZE 10
|
||||
#define MAX_GID_SID_CACHE_SIZE 100
|
||||
#define TURNOVER_GID_SID_CACHE_SIZE 10
|
||||
|
||||
static size_t n_uid_sid_cache = 0;
|
||||
static size_t n_gid_sid_cache = 0;
|
||||
|
||||
static struct uid_sid_cache {
|
||||
struct uid_sid_cache *next, *prev;
|
||||
uid_t uid;
|
||||
DOM_SID sid;
|
||||
enum SID_NAME_USE sidtype;
|
||||
} *uid_sid_cache_head;
|
||||
|
||||
static struct gid_sid_cache {
|
||||
struct gid_sid_cache *next, *prev;
|
||||
gid_t gid;
|
||||
DOM_SID sid;
|
||||
enum SID_NAME_USE sidtype;
|
||||
} *gid_sid_cache_head;
|
||||
|
||||
/*****************************************************************
|
||||
Find a SID given a uid.
|
||||
*****************************************************************/
|
||||
|
||||
static BOOL fetch_sid_from_uid_cache(const DOM_SID *psid, uid_t uid)
|
||||
{
|
||||
struct uid_sid_cache *pc;
|
||||
|
||||
for (pc = uid_sid_cache_head; pc; pc = pc->next) {
|
||||
if (pc->uid == uid) {
|
||||
fstring sid;
|
||||
*psid = pc->sid;
|
||||
DEBUG(3,("fetch sid from uid cache %u -> %s\n",
|
||||
(unsigned int)uid, sid_to_string(sid, psid)));
|
||||
DLIST_PROMOTE(uid_sid_cache_head, pc);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Find a uid given a SID.
|
||||
*****************************************************************/
|
||||
|
||||
static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
|
||||
{
|
||||
struct uid_sid_cache *pc;
|
||||
|
||||
for (pc = uid_sid_cache_head; pc; pc = pc->next) {
|
||||
if (sid_compare(&pc->sid, psid) == 0) {
|
||||
fstring sid;
|
||||
*puid = pc->uid;
|
||||
DEBUG(3,("fetch uid from cache %u -> %s\n",
|
||||
(unsigned int)*puid, sid_to_string(sid, psid)));
|
||||
DLIST_PROMOTE(uid_sid_cache_head, pc);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Store uid to SID mapping in cache.
|
||||
*****************************************************************/
|
||||
|
||||
static void store_uid_sid_cache(const DOM_SID *psid, uid_t uid)
|
||||
{
|
||||
struct uid_sid_cache *pc;
|
||||
|
||||
if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) {
|
||||
/* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */
|
||||
struct uid_sid_cache *pc_next;
|
||||
size_t i;
|
||||
|
||||
for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next)
|
||||
;
|
||||
for(; pc; pc = pc_next) {
|
||||
pc_next = pc->next;
|
||||
DLIST_REMOVE(uid_sid_cache_head,pc);
|
||||
SAFE_FREE(pc);
|
||||
n_uid_sid_cache--;
|
||||
}
|
||||
}
|
||||
|
||||
pc = (struct uid_sid_cache *)malloc(sizeof(struct uid_sid_cache));
|
||||
if (!pc)
|
||||
return;
|
||||
pc->uid = uid;
|
||||
sid_copy(&pc->sid, psid);
|
||||
DLIST_ADD(uid_sid_cache_head, pc);
|
||||
n_uid_sid_cache++;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Find a SID given a gid.
|
||||
*****************************************************************/
|
||||
|
||||
static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
|
||||
{
|
||||
struct gid_sid_cache *pc;
|
||||
|
||||
for (pc = gid_sid_cache_head; pc; pc = pc->next) {
|
||||
if (pc->gid == gid) {
|
||||
fstring sid;
|
||||
*psid = pc->sid;
|
||||
DEBUG(3,("fetch sid from gid cache %u -> %s\n",
|
||||
(unsigned int)gid, sid_to_string(sid, psid)));
|
||||
DLIST_PROMOTE(gid_sid_cache_head, pc);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Find a gid given a SID.
|
||||
*****************************************************************/
|
||||
|
||||
static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
|
||||
{
|
||||
struct gid_sid_cache *pc;
|
||||
|
||||
for (pc = gid_sid_cache_head; pc; pc = pc->next) {
|
||||
if (sid_compare(&pc->sid, psid) == 0) {
|
||||
fstring sid;
|
||||
*pgid = pc->gid;
|
||||
DEBUG(3,("fetch uid from cache %u -> %s\n",
|
||||
(unsigned int)*pgid, sid_to_string(sid, psid)));
|
||||
DLIST_PROMOTE(gid_sid_cache_head, pc);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Store gid to SID mapping in cache.
|
||||
*****************************************************************/
|
||||
|
||||
static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
|
||||
{
|
||||
struct gid_sid_cache *pc;
|
||||
|
||||
if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) {
|
||||
/* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */
|
||||
struct gid_sid_cache *pc_next;
|
||||
size_t i;
|
||||
|
||||
for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next)
|
||||
;
|
||||
for(; pc; pc = pc_next) {
|
||||
pc_next = pc->next;
|
||||
DLIST_REMOVE(gid_sid_cache_head,pc);
|
||||
SAFE_FREE(pc);
|
||||
n_gid_sid_cache--;
|
||||
}
|
||||
}
|
||||
|
||||
pc = (struct gid_sid_cache *)malloc(sizeof(struct gid_sid_cache));
|
||||
if (!pc)
|
||||
return;
|
||||
pc->gid = gid;
|
||||
sid_copy(&pc->sid, psid);
|
||||
DLIST_ADD(gid_sid_cache_head, pc);
|
||||
n_gid_sid_cache++;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*THE CANONICAL* convert uid_t to SID function.
|
||||
check idmap if uid is in idmap range, otherwise falls back to
|
||||
the legacy algorithmic mapping.
|
||||
A special cache is used for uids that maps to Wellknown SIDs
|
||||
Returns SID pointer.
|
||||
*****************************************************************/
|
||||
|
||||
NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
|
||||
{
|
||||
uid_t low, high;
|
||||
fstring sid;
|
||||
|
||||
if (fetch_sid_from_uid_cache(psid, uid))
|
||||
return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
|
||||
|
||||
if (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) {
|
||||
if (winbind_uid_to_sid(psid, uid)) {
|
||||
|
||||
DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
|
||||
(unsigned int)uid, sid_to_string(sid, psid)));
|
||||
|
||||
if (psid)
|
||||
store_uid_sid_cache(psid, uid);
|
||||
return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
|
||||
}
|
||||
}
|
||||
|
||||
local_uid_to_sid(psid, uid);
|
||||
|
||||
DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid)));
|
||||
|
||||
if (psid)
|
||||
store_uid_sid_cache(psid, uid);
|
||||
|
||||
return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*THE CANONICAL* convert gid_t to SID function.
|
||||
check idmap if gid is in idmap range, otherwise falls back to
|
||||
the legacy algorithmic mapping.
|
||||
Group mapping is used for gids that maps to Wellknown SIDs
|
||||
Returns SID pointer.
|
||||
*****************************************************************/
|
||||
|
||||
NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
|
||||
{
|
||||
gid_t low, high;
|
||||
fstring sid;
|
||||
|
||||
if (fetch_sid_from_gid_cache(psid, gid))
|
||||
return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
|
||||
|
||||
if (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) {
|
||||
if (winbind_gid_to_sid(psid, gid)) {
|
||||
|
||||
DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
|
||||
(unsigned int)gid, sid_to_string(sid, psid)));
|
||||
|
||||
if (psid)
|
||||
store_gid_sid_cache(psid, gid);
|
||||
return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
|
||||
}
|
||||
}
|
||||
|
||||
local_gid_to_sid(psid, gid);
|
||||
|
||||
DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid)));
|
||||
|
||||
if (psid)
|
||||
store_gid_sid_cache(psid, gid);
|
||||
|
||||
return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
*THE CANONICAL* convert SID to uid function.
|
||||
if it is a foreign sid or it is in idmap rid range check idmap,
|
||||
otherwise falls back to the legacy algorithmic mapping.
|
||||
A special cache is used for uids that maps to Wellknown SIDs
|
||||
Returns True if this name is a user sid and the conversion
|
||||
was done correctly, False if not.
|
||||
*****************************************************************/
|
||||
|
||||
NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
|
||||
{
|
||||
fstring dom_name, name, sid_str;
|
||||
enum SID_NAME_USE name_type;
|
||||
BOOL ret;
|
||||
|
||||
if (fetch_uid_from_cache(puid, psid))
|
||||
return NT_STATUS_OK;
|
||||
|
||||
/*
|
||||
* First we must look up the name and decide if this is a user sid.
|
||||
*/
|
||||
|
||||
if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) {
|
||||
DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n",
|
||||
sid_to_string(sid_str, psid) ));
|
||||
|
||||
ret = local_sid_to_uid(puid, psid, &name_type);
|
||||
if (ret)
|
||||
store_uid_sid_cache(psid, *puid);
|
||||
return (ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure this is a user sid.
|
||||
*/
|
||||
|
||||
if (name_type != SID_NAME_USER) {
|
||||
DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n",
|
||||
(unsigned int)name_type ));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* query only first */
|
||||
|
||||
if ( !winbind_sid_to_uid_query(puid, psid) )
|
||||
{
|
||||
DEBUG(10,("sid_to_uid: winbind query for sid %s failed.\n",
|
||||
sid_to_string(sid_str, psid) ));
|
||||
|
||||
/* see if we have a local mapping */
|
||||
|
||||
if ( local_sid_to_uid(puid, psid, &name_type) ) {
|
||||
store_uid_sid_cache(psid, *puid);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Call back to winbind to allocate a new uid */
|
||||
|
||||
if ( !winbind_sid_to_uid(puid, psid) ) {
|
||||
DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n",
|
||||
sid_to_string(sid_str, psid) ));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid),
|
||||
(unsigned int)*puid ));
|
||||
|
||||
store_uid_sid_cache(psid, *puid);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
/*****************************************************************
|
||||
*THE CANONICAL* convert SID to gid function.
|
||||
if it is a foreign sid or it is in idmap rid range check idmap,
|
||||
otherwise falls back to the legacy algorithmic mapping.
|
||||
Group mapping is used for gids that maps to Wellknown SIDs
|
||||
Returns True if this name is a user sid and the conversion
|
||||
was done correctly, False if not.
|
||||
*****************************************************************/
|
||||
|
||||
NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
|
||||
{
|
||||
fstring dom_name, name, sid_str;
|
||||
enum SID_NAME_USE name_type;
|
||||
BOOL ret;
|
||||
|
||||
if (fetch_gid_from_cache(pgid, psid))
|
||||
return NT_STATUS_OK;
|
||||
|
||||
/*
|
||||
* First we must look up the name and decide if this is a group sid.
|
||||
*/
|
||||
|
||||
if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
|
||||
DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n",
|
||||
sid_to_string(sid_str, psid) ));
|
||||
|
||||
ret = local_sid_to_gid(pgid, psid, &name_type);
|
||||
if (ret)
|
||||
store_gid_sid_cache(psid, *pgid);
|
||||
|
||||
return (ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure this is a group sid.
|
||||
*/
|
||||
|
||||
if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) {
|
||||
DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n",
|
||||
(unsigned int)name_type ));
|
||||
|
||||
ret = local_sid_to_gid(pgid, psid, &name_type);
|
||||
if (ret)
|
||||
store_gid_sid_cache(psid, *pgid);
|
||||
return (ret ? NT_STATUS_OK : NT_STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
/* query only first */
|
||||
|
||||
if ( !winbind_sid_to_gid_query(pgid, psid) )
|
||||
{
|
||||
DEBUG(10,("sid_to_gid: winbind query for sid %s failed.\n",
|
||||
sid_to_string(sid_str, psid) ));
|
||||
|
||||
/* see if we have a local mapping */
|
||||
|
||||
if ( local_sid_to_gid(pgid, psid, &name_type) ) {
|
||||
store_gid_sid_cache(psid, *pgid);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Call back to winbind to allocate a new uid */
|
||||
|
||||
if ( !winbind_sid_to_gid(pgid, psid) ) {
|
||||
DEBUG(10,("sid_to_uid: winbind failed to allocate a new gid for sid %s\n",
|
||||
sid_to_string(sid_str, psid) ));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
else
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid),
|
||||
(unsigned int)*pgid ));
|
||||
|
||||
store_gid_sid_cache(psid, *pgid);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,7 @@ static NTSTATUS contact_winbind_auth_crap(const char *username,
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
request.data.auth_crap.flags = flags;
|
||||
request.flags = flags;
|
||||
|
||||
fstrcpy(request.data.auth_crap.user, username);
|
||||
|
||||
@ -233,13 +233,13 @@ static NTSTATUS contact_winbind_auth_crap(const char *username,
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
if ((flags & WINBIND_PAM_LMKEY) && lm_key
|
||||
if ((flags & WBFLAG_PAM_LMKEY) && lm_key
|
||||
&& (memcmp(zeros, response.data.auth.first_8_lm_hash,
|
||||
sizeof(response.data.auth.first_8_lm_hash)) != 0)) {
|
||||
memcpy(lm_key, response.data.auth.first_8_lm_hash,
|
||||
sizeof(response.data.auth.first_8_lm_hash));
|
||||
}
|
||||
if ((flags & WINBIND_PAM_NTKEY) && nt_key
|
||||
if ((flags & WBFLAG_PAM_NTKEY) && nt_key
|
||||
&& (memcmp(zeros, response.data.auth.nt_session_key,
|
||||
sizeof(response.data.auth.nt_session_key)) != 0)) {
|
||||
memcpy(nt_key, response.data.auth.nt_session_key,
|
||||
@ -413,10 +413,10 @@ static BOOL check_auth_crap(void)
|
||||
x_setbuf(x_stdout, NULL);
|
||||
|
||||
if (request_lm_key)
|
||||
flags |= WINBIND_PAM_LMKEY;
|
||||
flags |= WBFLAG_PAM_LMKEY;
|
||||
|
||||
if (request_nt_key)
|
||||
flags |= WINBIND_PAM_NTKEY;
|
||||
flags |= WBFLAG_PAM_NTKEY;
|
||||
|
||||
nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
|
||||
opt_workstation,
|
||||
@ -494,8 +494,8 @@ static BOOL test_lm(void)
|
||||
ZERO_STRUCT(lm_key);
|
||||
ZERO_STRUCT(nt_key);
|
||||
|
||||
flags |= WINBIND_PAM_LMKEY;
|
||||
flags |= WINBIND_PAM_NTKEY;
|
||||
flags |= WBFLAG_PAM_LMKEY;
|
||||
flags |= WBFLAG_PAM_NTKEY;
|
||||
|
||||
SMBencrypt(opt_password, chall.data, lm_response.data);
|
||||
E_deshash(opt_password, lm_hash);
|
||||
@ -559,8 +559,8 @@ static BOOL test_lm_ntlm(void)
|
||||
ZERO_STRUCT(lm_key);
|
||||
ZERO_STRUCT(nt_key);
|
||||
|
||||
flags |= WINBIND_PAM_LMKEY;
|
||||
flags |= WINBIND_PAM_NTKEY;
|
||||
flags |= WBFLAG_PAM_LMKEY;
|
||||
flags |= WBFLAG_PAM_NTKEY;
|
||||
|
||||
SMBencrypt(opt_password,chall.data,lm_response.data);
|
||||
E_deshash(opt_password, lm_hash);
|
||||
@ -633,8 +633,8 @@ static BOOL test_ntlm(void)
|
||||
ZERO_STRUCT(lm_key);
|
||||
ZERO_STRUCT(nt_key);
|
||||
|
||||
flags |= WINBIND_PAM_LMKEY;
|
||||
flags |= WINBIND_PAM_NTKEY;
|
||||
flags |= WBFLAG_PAM_LMKEY;
|
||||
flags |= WBFLAG_PAM_NTKEY;
|
||||
|
||||
SMBNTencrypt(opt_password,chall.data,nt_response.data);
|
||||
E_md4hash(opt_password, nt_hash);
|
||||
@ -702,8 +702,8 @@ static BOOL test_ntlm_in_lm(void)
|
||||
|
||||
ZERO_STRUCT(nt_key);
|
||||
|
||||
flags |= WINBIND_PAM_LMKEY;
|
||||
flags |= WINBIND_PAM_NTKEY;
|
||||
flags |= WBFLAG_PAM_LMKEY;
|
||||
flags |= WBFLAG_PAM_NTKEY;
|
||||
|
||||
SMBNTencrypt(opt_password,chall.data,nt_response.data);
|
||||
|
||||
@ -771,8 +771,8 @@ static BOOL test_ntlm_in_both(void)
|
||||
ZERO_STRUCT(lm_key);
|
||||
ZERO_STRUCT(nt_key);
|
||||
|
||||
flags |= WINBIND_PAM_LMKEY;
|
||||
flags |= WINBIND_PAM_NTKEY;
|
||||
flags |= WBFLAG_PAM_LMKEY;
|
||||
flags |= WBFLAG_PAM_NTKEY;
|
||||
|
||||
SMBNTencrypt(opt_password,chall.data,nt_response.data);
|
||||
E_md4hash(opt_password, nt_hash);
|
||||
@ -842,7 +842,7 @@ static BOOL test_ntlmv2(void)
|
||||
|
||||
ZERO_STRUCT(nt_key);
|
||||
|
||||
flags |= WINBIND_PAM_NTKEY;
|
||||
flags |= WBFLAG_PAM_NTKEY;
|
||||
|
||||
if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall,
|
||||
&names_blob,
|
||||
@ -905,7 +905,7 @@ static BOOL test_lmv2_ntlmv2(void)
|
||||
|
||||
ZERO_STRUCT(nt_key);
|
||||
|
||||
flags |= WINBIND_PAM_NTKEY;
|
||||
flags |= WBFLAG_PAM_NTKEY;
|
||||
|
||||
if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall,
|
||||
&names_blob,
|
||||
@ -1016,8 +1016,8 @@ static BOOL test_ntlm_broken(BOOL break_lm)
|
||||
ZERO_STRUCT(lm_key);
|
||||
ZERO_STRUCT(nt_key);
|
||||
|
||||
flags |= WINBIND_PAM_LMKEY;
|
||||
flags |= WINBIND_PAM_NTKEY;
|
||||
flags |= WBFLAG_PAM_LMKEY;
|
||||
flags |= WBFLAG_PAM_NTKEY;
|
||||
|
||||
SMBencrypt(opt_password,chall.data,lm_response.data);
|
||||
E_deshash(opt_password, lm_hash);
|
||||
@ -1099,7 +1099,7 @@ static BOOL test_ntlmv2_broken(BOOL break_lmv2)
|
||||
|
||||
ZERO_STRUCT(nt_key);
|
||||
|
||||
flags |= WINBIND_PAM_NTKEY;
|
||||
flags |= WBFLAG_PAM_NTKEY;
|
||||
|
||||
if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall,
|
||||
&names_blob,
|
||||
|
@ -158,7 +158,7 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst
|
||||
char nt_passwd[33];
|
||||
|
||||
uid = -1;
|
||||
sid_to_uid(pdb_get_user_sid(sam_pwent), &uid);
|
||||
idmap_sid_to_uid(pdb_get_user_sid(sam_pwent), &uid, 0);
|
||||
pdb_sethexpwd(lm_passwd, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
|
||||
pdb_sethexpwd(nt_passwd, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
|
||||
|
||||
@ -171,7 +171,7 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst
|
||||
(uint32)pdb_get_pass_last_set_time(sam_pwent));
|
||||
} else {
|
||||
uid = -1;
|
||||
sid_to_uid(pdb_get_user_sid(sam_pwent), &uid);
|
||||
idmap_sid_to_uid(pdb_get_user_sid(sam_pwent), &uid, 0);
|
||||
printf ("%s:%d:%s\n", pdb_get_username(sam_pwent), uid, pdb_get_fullname(sam_pwent));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user