Copyright (C) Simo Sorce 2002-2003
Copyright (C) Gerald (Jerry) Carter 2005
Copyright (C) Michael Adam 2007
-
+
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 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
- * Basic privileges functions (mask-operations and conversion
+ * Basic privileges functions (mask-operations and conversion
* functions between the different formats (se_priv, privset, luid)
* moved here * from lib/privileges.c to minimize linker deps.
*
*
* some extra functions to hide privs array from lib/privileges.c
*/
-
+
#include "includes.h"
const SE_PRIV se_priv_all = SE_ALL_PRIVS;
/********************************************************************
This is a list of privileges reported by a WIndows 2000 SP4 AD DC
- just for reference purposes (and I know the LUID is not guaranteed
+ just for reference purposes (and I know the LUID is not guaranteed
across reboots):
SeCreateTokenPrivilege Create a token object ( 0x0, 0x2 )
/* we have to define the LUID here due to a horrible check by printmig.exe
that requires the SeBackupPrivilege match what is in Windows. So match
those that we implement and start Samba privileges at 0x1001 */
-
+
PRIVS privs[] = {
-#if 0 /* usrmgr will display these twice if you include them. We don't
+#if 0 /* usrmgr will display these twice if you include them. We don't
use them but we'll keep the bitmasks reserved in privileges.h anyways */
-
+
{SE_NETWORK_LOGON, "SeNetworkLogonRight", "Access this computer from network", { 0x0, 0x0 }},
{SE_INTERACTIVE_LOGON, "SeInteractiveLogonRight", "Log on locally", { 0x0, 0x0 }},
{SE_BATCH_LOGON, "SeBatchLogonRight", "Log on as a batch job", { 0x0, 0x0 }},
{SE_BACKUP, "SeBackupPrivilege", "Back up files and directories", { 0x0, 0x0011 }},
{SE_RESTORE, "SeRestorePrivilege", "Restore files and directories", { 0x0, 0x0012 }},
{SE_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Force shutdown from a remote system", { 0x0, 0x0018 }},
-
+
{SE_PRINT_OPERATOR, "SePrintOperatorPrivilege", "Manage printers", { 0x0, 0x1001 }},
{SE_ADD_USERS, "SeAddUsersPrivilege", "Add users and groups to the domain", { 0x0, 0x1002 }},
{SE_DISK_OPERATOR, "SeDiskOperatorPrivilege", "Manage disk shares", { 0x0, 0x1003 }},
{
if ( !dst || !src )
return False;
-
+
memcpy( dst, src, sizeof(SE_PRIV) );
-
+
return True;
}
return False;
}
for ( i=0; i<num_privs; i++ ) {
- se_priv_add(mask, &privs[i].se_priv);
+ se_priv_add(mask, &privs[i].se_priv);
}
return True;
}
}
/***************************************************************************
- remove one SE_PRIV sytucture from another and store the resulting set
+ remove one SE_PRIV sytucture from another and store the resulting set
in mew_mask
****************************************************************************/
void se_priv_remove( SE_PRIV *mask, const SE_PRIV *removepriv )
-{
+{
int i;
for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) {
****************************************************************************/
static void se_priv_invert( SE_PRIV *new_mask, const SE_PRIV *mask )
-{
+{
SE_PRIV allprivs;
-
+
se_priv_copy( &allprivs, &se_priv_all );
se_priv_remove( &allprivs, mask );
se_priv_copy( new_mask, &allprivs );
****************************************************************************/
bool se_priv_equal( const SE_PRIV *mask1, const SE_PRIV *mask2 )
-{
+{
return ( memcmp(mask1, mask2, sizeof(SE_PRIV)) == 0 );
}
{
SE_PRIV p1;
int i;
-
+
se_priv_copy( &p1, mask );
for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) {
p1.mask[i] &= se_priv_all.mask[i];
}
-
+
return se_priv_equal( &p1, &se_priv_none );
}
/*********************************************************************
- Lookup the SE_PRIV value for a privilege name
+ Lookup the SE_PRIV value for a privilege name
*********************************************************************/
bool se_priv_from_name( const char *name, SE_PRIV *mask )
void dump_se_priv( int dbg_cl, int dbg_lvl, const SE_PRIV *mask )
{
int i;
-
+
DEBUGADDC( dbg_cl, dbg_lvl,("SE_PRIV "));
-
+
for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) {
DEBUGADDC( dbg_cl, dbg_lvl,(" 0x%x", mask->mask[i] ));
}
-
+
DEBUGADDC( dbg_cl, dbg_lvl, ("\n"));
}
if ( !privileges || !check )
return False;
-
+
/* everyone has privileges if you aren't checking for any */
-
+
if ( se_priv_empty( check ) ) {
DEBUG(1,("is_privilege_assigned: no privileges in check_mask!\n"));
return True;
}
-
+
se_priv_copy( &p1, check );
-
- /* invert the SE_PRIV we want to check for and remove that from the
- original set. If we are left with the SE_PRIV we are checking
+
+ /* invert the SE_PRIV we want to check for and remove that from the
+ original set. If we are left with the SE_PRIV we are checking
for then return True */
-
+
se_priv_invert( &p1, check );
se_priv_copy( &p2, privileges );
se_priv_remove( &p2, &p1 );
-
+
return se_priv_equal( &p2, check );
}
if ( !privileges || !check )
return False;
-
+
/* everyone has privileges if you aren't checking for any */
-
+
if ( se_priv_empty( check ) ) {
DEBUG(1,("is_any_privilege_assigned: no privileges in check_mask!\n"));
return True;
}
-
+
se_priv_copy( &p1, check );
-
- /* invert the SE_PRIV we want to check for and remove that from the
- original set. If we are left with the SE_PRIV we are checking
+
+ /* invert the SE_PRIV we want to check for and remove that from the
+ original set. If we are left with the SE_PRIV we are checking
for then return True */
-
+
se_priv_invert( &p1, check );
se_priv_copy( &p2, privileges );
se_priv_remove( &p2, &p1 );
-
+
/* see if we have any bits left */
-
+
return !se_priv_empty( &p2 );
}
}
for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
-
+
if ( strequal( privs[i].name, name ) ) {
return privs[i].description;
}
}
/****************************************************************************
- initialise a privilege list and set the talloc context
+ initialise a privilege list and set the talloc context
****************************************************************************/
-
+
/****************************************************************************
Does the user have the specified privilege ? We only deal with one privilege
at a time here.
/*********************************************************************
Generate the LUID_ATTR structure based on a bitmask
The assumption here is that the privilege has already been validated
- so we are guaranteed to find it in the list.
+ so we are guaranteed to find it in the list.
*********************************************************************/
LUID_ATTR get_privilege_luid( SE_PRIV *mask )
int i;
ZERO_STRUCT( priv_luid );
-
+
for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
-
+
if ( se_priv_equal( &privs[i].se_priv, mask ) ) {
priv_luid.luid = privs[i].luid;
break;
return privs[i].name;
}
}
-
+
return NULL;
}
if ( !new_set ) {
DEBUG(0,("privilege_set_add: failed to allocate memory!\n"));
return False;
- }
+ }
new_set[priv_set->count].luid.high = set.luid.high;
new_set[priv_set->count].luid.low = set.luid.low;
int i;
uint32 num_privs = count_all_privileges();
LUID_ATTR luid;
-
+
luid.attr = 0;
luid.luid.high = 0;
-
+
for ( i=0; i<num_privs; i++ ) {
if ( !is_privilege_assigned(mask, &privs[i].se_priv) )
continue;
-
+
luid.luid = privs[i].luid;
-
+
if ( !privilege_set_add( set, luid ) )
return False;
}
{
int i;
uint32 num_privs = count_all_privileges();
-
+
for ( i=0; i<num_privs; i++ ) {
if ( luid->low == privs[i].luid.low ) {
se_priv_copy( mask, &privs[i].se_priv );
bool privilege_set_to_se_priv( SE_PRIV *mask, struct lsa_PrivilegeSet *privset )
{
int i;
-
+
ZERO_STRUCTP( mask );
-
+
for ( i=0; i<privset->count; i++ ) {
SE_PRIV r;
-
+
/* sanity check for invalid privilege. we really
only care about the low 32 bits */
-
+
if ( privset->set[i].luid.high != 0 )
return False;
-
- if ( luid_to_se_priv( &privset->set[i].luid, &r ) )
+
+ if ( luid_to_se_priv( &privset->set[i].luid, &r ) )
se_priv_add( mask, &r );
}