1998-03-12 00:11:04 +03:00
/*
* Unix SMB / Netbios implementation .
* Version 1.9 .
* RPC Pipe client / server routines
* Copyright ( C ) Andrew Tridgell 1992 - 1998
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1998 ,
* Copyright ( C ) Paul Ashton 1997 - 1998.
*
* 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 , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
1999-12-13 16:27:58 +03:00
/* this module apparently provides an implementation of DCE/RPC over a
* named pipe ( IPC $ connection using SMBtrans ) . details of DCE / RPC
* documentation are available ( in on - line form ) from the X - Open group .
*
* this module should provide a level of abstraction between SMB
* and DCE / RPC , while minimising the amount of mallocs , unnecessary
* data copies , and network traffic .
*
* in this version , which takes a " let's learn what's going on and
* get something running " approach, there is additional network
* traffic generated , but the code should be easier to understand . . .
*
* . . . if you read the docs . or stare at packets for weeks on end .
*
*/
# include "includes.h"
/*
* A list of the rids of well known BUILTIN and Domain users
* and groups .
*/
rid_name builtin_alias_rids [ ] =
{
{ BUILTIN_ALIAS_RID_ADMINS , " Administrators " } ,
{ BUILTIN_ALIAS_RID_USERS , " Users " } ,
{ BUILTIN_ALIAS_RID_GUESTS , " Guests " } ,
{ BUILTIN_ALIAS_RID_POWER_USERS , " Power Users " } ,
{ BUILTIN_ALIAS_RID_ACCOUNT_OPS , " Account Operators " } ,
{ BUILTIN_ALIAS_RID_SYSTEM_OPS , " System Operators " } ,
{ BUILTIN_ALIAS_RID_PRINT_OPS , " Print Operators " } ,
{ BUILTIN_ALIAS_RID_BACKUP_OPS , " Backup Operators " } ,
{ BUILTIN_ALIAS_RID_REPLICATOR , " Replicator " } ,
{ 0 , NULL }
} ;
/* array lookup of well-known Domain RID users. */
rid_name domain_user_rids [ ] =
{
{ DOMAIN_USER_RID_ADMIN , " Administrator " } ,
{ DOMAIN_USER_RID_GUEST , " Guest " } ,
{ 0 , NULL }
} ;
/* array lookup of well-known Domain RID groups. */
rid_name domain_group_rids [ ] =
{
{ DOMAIN_GROUP_RID_ADMINS , " Domain Admins " } ,
{ DOMAIN_GROUP_RID_USERS , " Domain Users " } ,
{ DOMAIN_GROUP_RID_GUESTS , " Domain Guests " } ,
{ 0 , NULL }
} ;
2001-03-11 03:32:10 +03:00
int make_dom_gids ( TALLOC_CTX * ctx , char * gids_str , DOM_GID * * ppgids )
1999-12-13 16:27:58 +03:00
{
char * ptr ;
pstring s2 ;
int count ;
DOM_GID * gids ;
* ppgids = NULL ;
DEBUG ( 4 , ( " make_dom_gids: %s \n " , gids_str ) ) ;
if ( gids_str = = NULL | | * gids_str = = 0 )
return 0 ;
for ( count = 0 , ptr = gids_str ;
next_token ( & ptr , s2 , NULL , sizeof ( s2 ) ) ;
count + + )
;
2001-03-11 03:32:10 +03:00
gids = ( DOM_GID * ) talloc ( ctx , sizeof ( DOM_GID ) * count ) ;
1999-12-13 16:27:58 +03:00
if ( ! gids )
{
2001-03-11 03:32:10 +03:00
DEBUG ( 0 , ( " make_dom_gids: talloc fail ! \n " ) ) ;
1999-12-13 16:27:58 +03:00
return 0 ;
}
for ( count = 0 , ptr = gids_str ;
next_token ( & ptr , s2 , NULL , sizeof ( s2 ) ) & &
count < LSA_MAX_GROUPS ;
count + + )
{
/* the entries are of the form GID/ATTR, ATTR being optional.*/
char * attr ;
uint32 rid = 0 ;
int i ;
2001-07-04 11:36:09 +04:00
attr = strchr_m ( s2 , ' / ' ) ;
1999-12-13 16:27:58 +03:00
if ( attr )
* attr + + = 0 ;
if ( ! attr | | ! * attr )
attr = " 7 " ; /* default value for attribute is 7 */
/* look up the RID string and see if we can turn it into a rid number */
for ( i = 0 ; builtin_alias_rids [ i ] . name ! = NULL ; i + + )
{
if ( strequal ( builtin_alias_rids [ i ] . name , s2 ) )
{
rid = builtin_alias_rids [ i ] . rid ;
break ;
}
}
if ( rid = = 0 )
rid = atoi ( s2 ) ;
if ( rid = = 0 )
{
DEBUG ( 1 , ( " make_dom_gids: unknown well-known alias RID %s/%s \n " , s2 , attr ) ) ;
count - - ;
}
else
{
gids [ count ] . g_rid = rid ;
gids [ count ] . attr = atoi ( attr ) ;
DEBUG ( 5 , ( " group id: %d attr: %d \n " , gids [ count ] . g_rid , gids [ count ] . attr ) ) ;
}
}
* ppgids = gids ;
return count ;
}
2001-12-05 00:53:47 +03:00
/*******************************************************************
gets a domain user ' s groups
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL new_get_domain_user_groups ( TALLOC_CTX * ctx , int * numgroups , DOM_GID * * pgids , SAM_ACCOUNT * sam_pass )
{
GROUP_MAP * map = NULL ;
int i , num , num_entries , cur_gid = 0 ;
struct group * grp ;
DOM_GID * gids ;
fstring user_name ;
uint32 grid ;
uint32 tmp_rid ;
fstrcpy ( user_name , pdb_get_username ( sam_pass ) ) ;
grid = pdb_get_group_rid ( sam_pass ) ;
DEBUG ( 10 , ( " new_get_domain_user_groups: searching domain groups [%s] is a member of \n " , user_name ) ) ;
/* first get the list of the domain groups */
if ( ! enum_group_mapping ( SID_NAME_DOM_GRP , & map , & num_entries , ENUM_ONLY_MAPPED , MAPPING_WITHOUT_PRIV ) )
return False ;
DEBUG ( 10 , ( " new_get_domain_user_groups: there are %d mapped groups \n " , num_entries ) ) ;
/*
* alloc memory . In the worse case , we alloc memory for nothing .
* but I prefer to alloc for nothing
* than reallocing everytime .
*/
gids = ( DOM_GID * ) talloc ( ctx , sizeof ( DOM_GID ) * num_entries ) ;
/* for each group, check if the user is a member of*/
for ( i = 0 ; i < num_entries ; i + + ) {
if ( ( grp = getgrgid ( map [ i ] . gid ) ) = = NULL ) {
/* very weird !!! */
DEBUG ( 5 , ( " new_get_domain_user_groups: gid %d doesn't exist anymore ! \n " , ( int ) map [ i ] . gid ) ) ;
continue ;
}
for ( num = 0 ; grp - > gr_mem [ num ] ! = NULL ; num + + ) {
if ( strcmp ( grp - > gr_mem [ num ] , user_name ) = = 0 ) {
/* we found the user, add the group to the list */
sid_peek_rid ( & map [ i ] . sid , & ( gids [ cur_gid ] . g_rid ) ) ;
gids [ cur_gid ] . attr = map [ i ] . sid_name_use ;
DEBUG ( 10 , ( " new_get_domain_user_groups: user found in group %s \n " , map [ i ] . nt_name ) ) ;
cur_gid + + ;
break ;
}
}
}
/* we have checked the groups */
/* we must now check the gid of the user or the primary group rid, that's the same */
for ( i = 0 ; i < cur_gid & & grid ! = gids [ i ] . g_rid ; i + + )
;
/* the user's gid is already there */
if ( i ! = cur_gid ) {
goto done ;
}
for ( i = 0 ; i < num_entries ; i + + ) {
sid_peek_rid ( & map [ i ] . sid , & tmp_rid ) ;
if ( tmp_rid = = grid ) {
gids [ cur_gid ] . g_rid = tmp_rid ;
gids [ cur_gid ] . attr = map [ i ] . sid_name_use ;
DEBUG ( 10 , ( " new_get_domain_user_groups: primary gid of user found in group %s \n " , map [ i ] . nt_name ) ) ;
cur_gid + + ;
goto done ; /* leave the loop early */
}
}
done :
* pgids = gids ;
* numgroups = cur_gid ;
safe_free ( map ) ;
}
1999-12-13 16:27:58 +03:00
/*******************************************************************
gets a domain user ' s groups
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
This commit is number 4 of 4.
In particular this commit focuses on:
Actually adding the 'const' to the passdb interface, and the flow-on changes.
Also kill off the 'disp_info' stuff, as its no longer used.
While these changes have been mildly tested, and are pretty small, any
assistance in this is appreciated.
----
These changes introduces a large dose of 'const' to the Samba tree.
There are a number of good reasons to do this:
- I want to allow the SAM_ACCOUNT structure to move from wasteful
pstrings and fstrings to allocated strings. We can't do that if
people are modifying these outputs, as they may well make
assumptions about getting pstrings and fstrings
- I want --with-pam_smbpass to compile with a slightly sane
volume of warnings, currently its pretty bad, even in 2.2
where is compiles at all.
- Tridge assures me that he no longer opposes 'const religion'
based on the ability to #define const the problem away.
- Changed Get_Pwnam(x,y) into two variants (so that the const
parameter can work correctly): - Get_Pwnam(const x) and
Get_Pwnam_Modify(x).
- Reworked smbd/chgpasswd.c to work with these mods, passing
around a 'struct passwd' rather than the modified username
---
This finishes this line of commits off, your tree should now compile again :-)
Andrew Bartlett
(This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317)
2001-10-29 10:35:11 +03:00
void get_domain_user_groups ( char * domain_groups , const char * user )
1999-12-13 16:27:58 +03:00
{
pstring tmp ;
if ( domain_groups = = NULL | | user = = NULL ) return ;
/* can only be a user or a guest. cannot be guest _and_ admin */
if ( user_in_list ( user , lp_domain_guest_group ( ) ) )
{
slprintf ( tmp , sizeof ( tmp ) - 1 , " %ld/7 " , DOMAIN_GROUP_RID_GUESTS ) ;
pstrcat ( domain_groups , tmp ) ;
DEBUG ( 3 , ( " domain guest group access %s granted \n " , tmp ) ) ;
}
else
{
slprintf ( tmp , sizeof ( tmp ) - 1 , " %ld/7 " , DOMAIN_GROUP_RID_USERS ) ;
pstrcat ( domain_groups , tmp ) ;
DEBUG ( 3 , ( " domain group access %s granted \n " , tmp ) ) ;
if ( user_in_list ( user , lp_domain_admin_group ( ) ) )
{
slprintf ( tmp , sizeof ( tmp ) - 1 , " %ld/7 " , DOMAIN_GROUP_RID_ADMINS ) ;
pstrcat ( domain_groups , tmp ) ;
DEBUG ( 3 , ( " domain admin group access %s granted \n " , tmp ) ) ;
}
}
}
/*******************************************************************
2001-03-11 03:32:10 +03:00
Look up a local ( domain ) rid and return a name and type .
1999-12-13 16:27:58 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS local_lookup_group_name ( uint32 rid , char * group_name , uint32 * type )
1999-12-13 16:27:58 +03:00
{
int i = 0 ;
( * type ) = SID_NAME_DOM_GRP ;
DEBUG ( 5 , ( " lookup_group_name: rid: %d " , rid ) ) ;
while ( domain_group_rids [ i ] . rid ! = rid & & domain_group_rids [ i ] . rid ! = 0 )
{
i + + ;
}
if ( domain_group_rids [ i ] . rid ! = 0 )
{
fstrcpy ( group_name , domain_group_rids [ i ] . name ) ;
DEBUG ( 5 , ( " = %s \n " , group_name ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
1999-12-13 16:27:58 +03:00
}
DEBUG ( 5 , ( " none mapped \n " ) ) ;
2000-08-01 22:32:34 +04:00
return NT_STATUS_NONE_MAPPED ;
1999-12-13 16:27:58 +03:00
}
/*******************************************************************
2001-03-11 03:32:10 +03:00
Look up a local alias rid and return a name and type .
1999-12-13 16:27:58 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS local_lookup_alias_name ( uint32 rid , char * alias_name , uint32 * type )
1999-12-13 16:27:58 +03:00
{
int i = 0 ;
( * type ) = SID_NAME_WKN_GRP ;
DEBUG ( 5 , ( " lookup_alias_name: rid: %d " , rid ) ) ;
while ( builtin_alias_rids [ i ] . rid ! = rid & & builtin_alias_rids [ i ] . rid ! = 0 )
{
i + + ;
}
if ( builtin_alias_rids [ i ] . rid ! = 0 )
{
fstrcpy ( alias_name , builtin_alias_rids [ i ] . name ) ;
DEBUG ( 5 , ( " = %s \n " , alias_name ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
1999-12-13 16:27:58 +03:00
}
DEBUG ( 5 , ( " none mapped \n " ) ) ;
2000-08-01 22:32:34 +04:00
return NT_STATUS_NONE_MAPPED ;
1999-12-13 16:27:58 +03:00
}
/*******************************************************************
2001-03-11 03:32:10 +03:00
Look up a local user rid and return a name and type .
1999-12-13 16:27:58 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS local_lookup_user_name ( uint32 rid , char * user_name , uint32 * type )
1999-12-13 16:27:58 +03:00
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * sampwd = NULL ;
1999-12-13 16:27:58 +03:00
int i = 0 ;
2001-05-04 19:44:27 +04:00
BOOL ret ;
1999-12-13 16:27:58 +03:00
( * type ) = SID_NAME_USER ;
DEBUG ( 5 , ( " lookup_user_name: rid: %d " , rid ) ) ;
/* look up the well-known domain user rids first */
while ( domain_user_rids [ i ] . rid ! = rid & & domain_user_rids [ i ] . rid ! = 0 )
{
i + + ;
}
2001-05-04 19:44:27 +04:00
if ( domain_user_rids [ i ] . rid ! = 0 ) {
1999-12-13 16:27:58 +03:00
fstrcpy ( user_name , domain_user_rids [ i ] . name ) ;
DEBUG ( 5 , ( " = %s \n " , user_name ) ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
1999-12-13 16:27:58 +03:00
}
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & sampwd ) ;
1999-12-13 16:27:58 +03:00
/* ok, it's a user. find the user account */
2000-06-23 09:53:18 +04:00
become_root ( ) ;
2001-05-04 19:44:27 +04:00
ret = pdb_getsampwrid ( sampwd , rid ) ;
2000-06-23 09:53:18 +04:00
unbecome_root ( ) ;
1999-12-13 16:27:58 +03:00
2001-05-04 19:44:27 +04:00
if ( ret = = True ) {
2001-03-11 03:32:10 +03:00
fstrcpy ( user_name , pdb_get_username ( sampwd ) ) ;
1999-12-13 16:27:58 +03:00
DEBUG ( 5 , ( " = %s \n " , user_name ) ) ;
2001-09-29 17:08:26 +04:00
pdb_free_sam ( & sampwd ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
1999-12-13 16:27:58 +03:00
}
DEBUG ( 5 , ( " none mapped \n " ) ) ;
2001-09-29 17:08:26 +04:00
pdb_free_sam ( & sampwd ) ;
2000-08-01 22:32:34 +04:00
return NT_STATUS_NONE_MAPPED ;
1999-12-13 16:27:58 +03:00
}
/*******************************************************************
2001-03-11 03:32:10 +03:00
Look up a local ( domain ) group name and return a rid
1999-12-13 16:27:58 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS local_lookup_group_rid ( char * group_name , uint32 * rid )
1999-12-13 16:27:58 +03:00
{
char * grp_name ;
int i = - 1 ; /* start do loop at -1 */
do /* find, if it exists, a group rid for the group name*/
{
i + + ;
( * rid ) = domain_group_rids [ i ] . rid ;
grp_name = domain_group_rids [ i ] . name ;
} while ( grp_name ! = NULL & & ! strequal ( grp_name , group_name ) ) ;
2001-08-27 23:46:22 +04:00
return ( grp_name ! = NULL ) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED ;
1999-12-13 16:27:58 +03:00
}
/*******************************************************************
2001-03-11 03:32:10 +03:00
Look up a local ( BUILTIN ) alias name and return a rid
1999-12-13 16:27:58 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS local_lookup_alias_rid ( char * alias_name , uint32 * rid )
1999-12-13 16:27:58 +03:00
{
char * als_name ;
int i = - 1 ; /* start do loop at -1 */
do /* find, if it exists, a alias rid for the alias name*/
{
i + + ;
( * rid ) = builtin_alias_rids [ i ] . rid ;
als_name = builtin_alias_rids [ i ] . name ;
} while ( als_name ! = NULL & & ! strequal ( als_name , alias_name ) ) ;
2001-08-27 23:46:22 +04:00
return ( als_name ! = NULL ) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED ;
1999-12-13 16:27:58 +03:00
}
/*******************************************************************
2001-03-11 03:32:10 +03:00
Look up a local user name and return a rid
1999-12-13 16:27:58 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS local_lookup_user_rid ( char * user_name , uint32 * rid )
1999-12-13 16:27:58 +03:00
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * sampass = NULL ;
BOOL ret ;
1999-12-13 16:27:58 +03:00
( * rid ) = 0 ;
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & sampass ) ;
1999-12-13 16:27:58 +03:00
/* find the user account */
2000-06-23 09:53:18 +04:00
become_root ( ) ;
2001-05-04 19:44:27 +04:00
ret = pdb_getsampwnam ( sampass , user_name ) ;
2000-06-23 09:53:18 +04:00
unbecome_root ( ) ;
1999-12-13 16:27:58 +03:00
2001-05-04 19:44:27 +04:00
if ( ret = = True ) {
2001-03-11 03:32:10 +03:00
( * rid ) = pdb_get_user_rid ( sampass ) ;
2001-09-29 17:08:26 +04:00
pdb_free_sam ( & sampass ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
1999-12-13 16:27:58 +03:00
}
2001-09-29 17:08:26 +04:00
pdb_free_sam ( & sampass ) ;
2000-08-01 22:32:34 +04:00
return NT_STATUS_NONE_MAPPED ;
1999-12-13 16:27:58 +03:00
}