r4849: * finish SeAddUsers support in srv_samr_nt.c
authorGerald Carter <jerry@samba.org>
Wed, 19 Jan 2005 16:52:19 +0000 (16:52 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:53:59 +0000 (10:53 -0500)
* define some const SE_PRIV structure for use when
  you need a SE_PRIV* to a privilege
* fix an annoying compiler warngin in smbfilter.c
* translate SIDs to names in 'net rpc rights list accounts'
* fix a seg fault in cli_lsa_enum_account_rights caused by
  me forgetting the precedence of * vs. []
(This used to be commit d25fc84bc2b14da9fcc0f3c8d7baeca83f0ea708)

source3/include/privileges.h
source3/lib/privileges.c
source3/rpc_client/cli_lsarpc.c
source3/rpc_server/srv_samr_nt.c
source3/utils/net_rpc_rights.c
source3/utils/smbfilter.c

index 85087f624f91c24be5923ce6baa5c33695b9d056..76cabf3ba905a1df1095e5fc0c6e8e681eb3fab8 100644 (file)
 #ifndef PRIVILEGES_H
 #define PRIVILEGES_H
 
+/* privilege bitmask */
+
+#define SE_PRIV_MASKSIZE 4
+
+typedef struct {
+       uint32 mask[SE_PRIV_MASKSIZE];
+} SE_PRIV;
+
+
 /* common privilege defines */
 
 #define SE_END                         { { 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }
 #define SE_DISK_OPERATOR               { { 0x00000080, 0x00000000, 0x00000000, 0x00000000 } }
 #define SE_REMOTE_SHUTDOWN             { { 0x00000100, 0x00000000, 0x00000000, 0x00000000 } }
 
-#if 0  /* not needed currently */
-
-#define SE_ASSIGN_PRIMARY_TOKEN        
-#define SE_CREATE_TOKEN                
-#define SE_LOCK_MEMORY         
-#define SE_INCREASE_QUOTA      
-#define SE_UNSOLICITED_INPUT
-#define SE_TCB 
-#define SE_SECURITY    
-#define SE_TAKE_OWNERSHIP
-#define SE_LOAD_DRIVER 
-#define SE_SYSTEM_PROFILE      
-#define SE_SYSTEM_TIME 
-#define SE_PROF_SINGLE_PROCESS 
-#define SE_INC_BASE_PRIORITY
-#define SE_CREATE_PAGEFILE
-#define SE_CREATE_PERMANENT    
-#define SE_BACKUP
-#define SE_RESTORE
-#define SE_SHUTDOWN    
-#define SE_DEBUG
-#define SE_AUDIT       
-#define SE_SYSTEM_ENVIRONMENT  
-#define SE_CHANGE_NOTIFY
-#define SE_REMOTE_SHUTDOWN
-#define SE_UNDOCK
-#define SE_SYNC_AGENT  
-#define SE_ENABLE_DELEGATION
-
-#endif /* not needed currently */
+/* defined in lib/privilegs.c */
+
+extern const SE_PRIV se_machine_account;
+extern const SE_PRIV se_print_operator;
+extern const SE_PRIV se_add_users;
+extern const SE_PRIV se_disk_operators;
+extern const SE_PRIV se_remote_shutdown;
+
 
 /*
  * These are used in Lsa replies (srv_lsa_nt.c)
@@ -115,12 +102,6 @@ typedef struct privilege_set
        LUID_ATTR *set;
 } PRIVILEGE_SET;
 
-#define SE_PRIV_MASKSIZE 4
-
-typedef struct {
-       uint32 mask[SE_PRIV_MASKSIZE];
-} SE_PRIV;
-
 typedef struct _PRIVS {
        SE_PRIV se_priv;
        const char *name;
index df785f801efe2b341ff0115cdcf921bbf7de6082..628b2dd32516e368c42c754cb45e0ff529071c96 100644 (file)
@@ -31,6 +31,15 @@ static SE_PRIV se_priv_all  = SE_ALL_PRIVS;
 static SE_PRIV se_priv_end  = SE_END;
 static SE_PRIV se_priv_none = SE_NONE;
 
+/* Define variables for all privileges so we can use the
+   SE_PRIV* in the various se_priv_XXX() functions */
+
+const SE_PRIV se_machine_account = SE_MACHINE_ACCOUNT;
+const SE_PRIV se_print_operator  = SE_PRINT_OPERATOR;
+const SE_PRIV se_add_users       = SE_ADD_USERS;
+const SE_PRIV se_disk_operators  = SE_DISK_OPERATOR;
+const SE_PRIV se_remote_shutdown = SE_REMOTE_SHUTDOWN;
+
 PRIVS privs[] = {
 #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 */
@@ -56,7 +65,6 @@ PRIVS privs[] = {
        {SE_LOCK_MEMORY,                "SeLockMemoryPrivilege",                "Lock Memory"},
        {SE_INCREASE_QUOTA,             "SeIncreaseQuotaPrivilege",             "Increase Quota"},
        {SE_UNSOLICITED_INPUT,          "SeUnsolicitedInputPrivilege",          "Unsolicited Input"},
-       {SE_MACHINE_ACCOUNT,            "SeMachineAccountPrivilege",            "Can add Machine Accounts to the Domain"},
        {SE_TCB,                        "SeTcbPrivilege",                       "Act as part of the operating system"},
        {SE_SECURITY,                   "SeSecurityPrivilege",                  "Security Privilege"},
        {SE_TAKE_OWNERSHIP,             "SeTakeOwnershipPrivilege",             "Take Ownership Privilege"},
@@ -92,7 +100,7 @@ typedef struct priv_sid_list {
  copy an SE_PRIV structure
 ****************************************************************************/
 
-BOOL se_priv_copy( SE_PRIV *dst, SE_PRIV *src )
+BOOL se_priv_copy( SE_PRIV *dst, const SE_PRIV *src )
 {
        if ( !dst || !src )
                return False;
@@ -106,7 +114,7 @@ BOOL se_priv_copy( SE_PRIV *dst, SE_PRIV *src )
  combine 2 SE_PRIV structures and store the resulting set in mew_mask
 ****************************************************************************/
 
-static void se_priv_add( SE_PRIV *mask, SE_PRIV *addpriv )
+static void se_priv_add( SE_PRIV *mask, const SE_PRIV *addpriv )
 {
        int i;
 
@@ -120,7 +128,7 @@ static void se_priv_add( SE_PRIV *mask, SE_PRIV *addpriv )
  in mew_mask
 ****************************************************************************/
 
-static void se_priv_remove( SE_PRIV *mask, SE_PRIV *removepriv )
+static void se_priv_remove( SE_PRIV *mask, const SE_PRIV *removepriv )
 {      
        int i;
 
@@ -133,7 +141,7 @@ static void se_priv_remove( SE_PRIV *mask, SE_PRIV *removepriv )
  invert a given SE_PRIV and store the set in new_mask
 ****************************************************************************/
 
-static void se_priv_invert( SE_PRIV *new_mask, SE_PRIV *mask )
+static void se_priv_invert( SE_PRIV *new_mask, const SE_PRIV *mask )
 {      
        SE_PRIV allprivs;
        
@@ -146,7 +154,7 @@ static void se_priv_invert( SE_PRIV *new_mask, SE_PRIV *mask )
  check if 2 SE_PRIV structure are equal
 ****************************************************************************/
 
-static BOOL se_priv_equal( SE_PRIV *mask1, SE_PRIV *mask2 )
+static BOOL se_priv_equal( const SE_PRIV *mask1, const SE_PRIV *mask2 )
 {      
        return ( memcmp(mask1, mask2, sizeof(SE_PRIV)) == 0 );
 }
@@ -156,7 +164,7 @@ static BOOL se_priv_equal( SE_PRIV *mask1, SE_PRIV *mask2 )
  dump an SE_PRIV structure to the log files
 ****************************************************************************/
 
-void dump_se_priv( int dbg_cl, int dbg_lvl, SE_PRIV *mask )
+void dump_se_priv( int dbg_cl, int dbg_lvl, const SE_PRIV *mask )
 {
        int i;
        
@@ -624,6 +632,9 @@ NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_l
 
 BOOL user_has_privileges(NT_USER_TOKEN *token, SE_PRIV *privilege)
 {
+       if ( !token )
+               return False;
+
        return is_privilege_assigned( &token->privileges, privilege );
 }
 
index bf2c0353c04e57c6efd3f5f7b92e819aa38067d9..98c2475a65833f683656f6a8d6c784c7b247afce 100644 (file)
@@ -1218,7 +1218,7 @@ NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
 NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                     POLICY_HND *pol, DOM_SID *sid,
-                                    uint32 *count, char ***privs_name)
+                                    uint32 *count, char ***priv_names)
 {
        prs_struct qbuf, rbuf;
        LSA_Q_ENUM_ACCT_RIGHTS q;
@@ -1226,6 +1226,7 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        NTSTATUS result;
        int i;
        fstring *privileges;
+       char **names;
 
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
@@ -1260,15 +1261,17 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        
        privileges = TALLOC_ARRAY(mem_ctx, fstring, *count);
-       *privs_name = TALLOC_ARRAY(mem_ctx, char *, *count);
+       names = TALLOC_ARRAY(mem_ctx, char *, *count);
        for ( i=0; i<*count; i++ ) {
                /* ensure NULL termination ... what a hack */
                pull_ucs2(NULL, privileges[i], r.rights.strings[i].string.buffer, 
                        sizeof(fstring), r.rights.strings[i].string.uni_str_len*2 , 0);
                        
                /* now copy to the return array */
-               *privs_name[i] = talloc_strdup( mem_ctx, privileges[i] );
+               names[i] = talloc_strdup( mem_ctx, privileges[i] );
        }
+       
+       *priv_names = names;
 
 done:
 
index 70c0de7da784b6481fd1f601ec4a43c68124dfd1..5fd5137cf1a413278b131e96901a0b9b5518f7eb 100644 (file)
@@ -1,14 +1,14 @@
 /*
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-1997,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *  Copyright (C) Andrew Tridgell                   1992-1997,
+ *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
  *  Copyright (C) Paul Ashton                       1997,
  *  Copyright (C) Marc Jacobsen                            1999,
- *  Copyright (C) Jeremy Allison               2001-2002,
- *  Copyright (C) Jean François Micouleau      1998-2001,
+ *  Copyright (C) Jeremy Allison                    2001-2002,
+ *  Copyright (C) Jean François Micouleau          1998-2001,
  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
- *  Copyright (C) Gerald (Jerry) Carter             2003 - 2004,
+ *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
  *
  *  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
@@ -2221,8 +2221,8 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
        uint32 new_rid = 0;
        /* check this, when giving away 'add computer to domain' privs */
        uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
-       BOOL can_add_machines = False;
-       SE_PRIV se_machineop = SE_MACHINE_ACCOUNT;
+       BOOL can_add_account;
+       SE_PRIV se_rights;
 
        /* Get the domain SID stored in the domain policy */
        if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
@@ -2246,14 +2246,7 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
 
        rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
        strlower_m(account);
-       
-       /* check to see if we are a domain admin */
-       
-       can_add_machines = user_has_privileges( p->pipe_user.nt_user_token, &se_machineop );
-       
-       DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
-               p->pipe_user_name, can_add_machines ? "" : " not"));
-
+               
        pdb_init_sam(&sam_pass);
 
        become_root();
@@ -2266,13 +2259,6 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
        }
 
        pdb_free_sam(&sam_pass);
-
-       /*
-        * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
-        * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
-        * that only people with write access to the smbpasswd file will be able
-        * to create a user. JRA.
-        */   
        
        /*********************************************************************
         * HEADS UP!  If we have to create a new user account, we have to get 
@@ -2287,26 +2273,37 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
        
        pw = Get_Pwnam(account);
        
-       /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
+       /* 
+        * we can't check both the ending $ and the acb_info.
+        * 
+        * UserManager creates trust accounts (ending in $,
+        * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
+        * JFM, 11/29/2001
+        */
+
+       if (account[strlen(account)-1] == '$') {
+               se_priv_copy( &se_rights, &se_machine_account );
+               pstrcpy(add_script, lp_addmachine_script());
+       }
+       else {
+               se_priv_copy( &se_rights, &se_add_users );
+               pstrcpy(add_script, lp_adduser_script());
+       }
+               
+       can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+       DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
+               p->pipe_user_name, can_add_account ? "True":"False" ));
+               
+       /********** BEGIN Admin BLOCK **********/
        
-       if ( can_add_machines )                         
+       if ( can_add_account )
                become_root();
-       
+                               
        if ( !pw ) {
-               /* 
-                * we can't check both the ending $ and the acb_info.
-                * 
-                * UserManager creates trust accounts (ending in $,
-                * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
-                * JFM, 11/29/2001
-                */
-               if (account[strlen(account)-1] == '$')
-                       pstrcpy(add_script, lp_addmachine_script());            
-               else 
-                       pstrcpy(add_script, lp_adduser_script());
-
                if (*add_script) {
                        int add_ret;
+                       
                        all_string_sub(add_script, "%u", account, sizeof(add_script));
                        add_ret = smbrun(add_script,NULL);
                        DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
@@ -2323,28 +2320,32 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
        
        /* implicit call to getpwnam() next.  we have a valid SID coming out of this call */
 
-       if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) ) {
-               if ( can_add_machines )
-                       unbecome_root();
-               return nt_status;
+       nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
+
+       /* this code is order such that we have no unnecessary retuns 
+          out of the admin block of code */    
+          
+       if ( NT_STATUS_IS_OK(nt_status) ) {
+               pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
+       
+               if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
+                       pdb_free_sam(&sam_pass);
+                       DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
+                               account));
+                       nt_status = NT_STATUS_ACCESS_DENIED;
+               }
        }
                
-       pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
-       
-       ret = pdb_add_sam_account(sam_pass);
-       
-       if ( can_add_machines )                         
+       if ( can_add_account )
                unbecome_root();
-               
-       /* ================ END SeMachineAccountPrivilege BLOCK ================ */
 
-       if ( !ret ) {
-               pdb_free_sam(&sam_pass);
-               DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
-                         account));
-               return NT_STATUS_ACCESS_DENIED;         
-       }
-       
+       /********** END Admin BLOCK **********/
+       
+       /* now check for failure */
+       
+       if ( !NT_STATUS_IS_OK(nt_status) )
+               return nt_status;
+                       
        /* Get the user's SID */
        
        sid_copy(&sid, pdb_get_user_sid(sam_pass));
@@ -3515,6 +3516,10 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD
 {
        DOM_SID alias_sid;
        uint32 acc_granted;
+       SE_PRIV se_rights;
+       BOOL can_add_accounts;
+       BOOL ret;
+
 
        /* Find the policy handle. Open a policy on it. */
        if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
@@ -3525,11 +3530,23 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD
        }
                
        DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
+       
+       se_priv_copy( &se_rights, &se_add_users );
+       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
 
-       if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
-               return NT_STATUS_ACCESS_DENIED;
-
-       return NT_STATUS_OK;
+       /******** BEGIN SeAddUsers BLOCK *********/
+       
+       if ( can_add_accounts )
+               become_root();
+       
+       ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
+       
+       if ( can_add_accounts )
+               unbecome_root();
+               
+       /******** END SeAddUsers BLOCK *********/
+       
+       return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
 }
 
 /*********************************************************************
@@ -3540,6 +3557,9 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE
 {
        DOM_SID alias_sid;
        uint32 acc_granted;
+       SE_PRIV se_rights;
+       BOOL can_add_accounts;
+       BOOL ret;
 
        /* Find the policy handle. Open a policy on it. */
        if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
@@ -3552,10 +3572,22 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE
        DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
                   sid_string_static(&alias_sid)));
 
-       if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
-               return NT_STATUS_ACCESS_DENIED;
+       se_priv_copy( &se_rights, &se_add_users );
+       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+       /******** BEGIN SeAddUsers BLOCK *********/
        
-       return NT_STATUS_OK;
+       if ( can_add_accounts )
+               become_root();
+
+       ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
+       
+       if ( can_add_accounts )
+               unbecome_root();
+               
+       /******** END SeAddUsers BLOCK *********/
+       
+       return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
 }
 
 /*********************************************************************
@@ -3576,6 +3608,8 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
        SAM_ACCOUNT *sam_user=NULL;
        BOOL check;
        uint32 acc_granted;
+       SE_PRIV se_rights;
+       BOOL can_add_accounts;
 
        /* Find the policy handle. Open a policy on it. */
        if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
@@ -3636,6 +3670,14 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
                return NT_STATUS_MEMBER_IN_GROUP;
        }
 
+       se_priv_copy( &se_rights, &se_add_users );
+       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+       /******** BEGIN SeAddUsers BLOCK *********/
+       
+       if ( can_add_accounts )
+               become_root();
+               
        /* 
         * ok, the group exist, the user exist, the user is not in the group,
         *
@@ -3644,6 +3686,11 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
 
        smb_add_user_group(grp_name, pwd->pw_name);
 
+       if ( can_add_accounts )
+               unbecome_root();
+               
+       /******** END SeAddUsers BLOCK *********/
+       
        /* check if the user has been added then ... */
        if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
                passwd_free(&pwd);
@@ -3667,6 +3714,8 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE
        fstring grp_name;
        struct group *grp;
        uint32 acc_granted;
+       SE_PRIV se_rights;
+       BOOL can_add_accounts;
 
        /*
         * delete the group member named q_u->rid
@@ -3710,9 +3759,23 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE
                pdb_free_sam(&sam_pass);
                return NT_STATUS_MEMBER_NOT_IN_GROUP;
        }
+       
 
+       se_priv_copy( &se_rights, &se_add_users );
+       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+       /******** BEGIN SeAddUsers BLOCK *********/
+       
+       if ( can_add_accounts )
+               become_root();
+               
        smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
 
+       if ( can_add_accounts )
+               unbecome_root();
+               
+       /******** END SeAddUsers BLOCK *********/
+       
        /* check if the user has been removed then ... */
        if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
                pdb_free_sam(&sam_pass);
@@ -3764,6 +3827,9 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
        DOM_SID user_sid;
        SAM_ACCOUNT *sam_pass=NULL;
        uint32 acc_granted;
+       SE_PRIV se_rights;
+       BOOL can_add_accounts;
+       BOOL ret;
 
        DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
 
@@ -3786,22 +3852,40 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
                pdb_free_sam(&sam_pass);
                return NT_STATUS_NO_SUCH_USER;
        }
+       
+       se_priv_copy( &se_rights, &se_add_users );
+       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
 
-       /* First delete the samba side */
-       if (!pdb_delete_sam_account(sam_pass)) {
+       /******** BEGIN SeAddUsers BLOCK *********/
+       
+       if ( can_add_accounts )
+               become_root();
+
+       /* First delete the samba side....
+          code is order to prevent unnecessary returns out of the admin 
+          block of code */
+          
+       if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
+               /*
+                * Now delete the unix side ....
+                * note: we don't check if the delete really happened
+                * as the script is not necessary present
+                * and maybe the sysadmin doesn't want to delete the unix side
+                */
+               smb_delete_user( pdb_get_username(sam_pass) );
+       }
+       
+       if ( can_add_accounts )
+               unbecome_root();
+               
+       /******** END SeAddUsers BLOCK *********/
+               
+       if ( !ret ) {
                DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
                pdb_free_sam(&sam_pass);
                return NT_STATUS_CANNOT_DELETE;
        }
 
-       /* Now delete the unix side */
-       /*
-        * note: we don't check if the delete really happened
-        * as the script is not necessary present
-        * and maybe the sysadmin doesn't want to delete the unix side
-        */
-       smb_delete_user(pdb_get_username(sam_pass));
-
 
        pdb_free_sam(&sam_pass);
 
@@ -3825,6 +3909,9 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S
        struct group *grp;
        GROUP_MAP map;
        uint32 acc_granted;
+       SE_PRIV se_rights;
+       BOOL can_add_accounts;
+       BOOL ret;
 
        DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
 
@@ -3857,17 +3944,33 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S
        if ( (grp=getgrgid(gid)) == NULL)
                return NT_STATUS_NO_SUCH_GROUP;
 
+       se_priv_copy( &se_rights, &se_add_users );
+       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+       /******** BEGIN SeAddUsers BLOCK *********/
+       
+       if ( can_add_accounts )
+               become_root();
+
        /* delete mapping first */
-       if(!pdb_delete_group_mapping_entry(group_sid))
-               return NT_STATUS_ACCESS_DENIED;
-               
-       /* we can delete the UNIX group */
-       smb_delete_group(grp->gr_name);
+       
+       if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
+               smb_delete_group( grp->gr_name );
+       }
 
-       /* check if the group has been successfully deleted */
-       if ( (grp=getgrgid(gid)) != NULL)
+       if ( can_add_accounts )
+               unbecome_root();
+               
+       /******** END SeAddUsers BLOCK *********/
+       
+       if ( !ret ) {
+               DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n", 
+                       group_sid_str));
                return NT_STATUS_ACCESS_DENIED;
-
+       }
+       
+       /* don't check that the unix group has been deleted.  Work like 
+          _samr_delet_dom_user() */
 
        if (!close_policy_hnd(p, &q_u->group_pol))
                return NT_STATUS_OBJECT_NAME_INVALID;
@@ -3883,6 +3986,9 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S
 {
        DOM_SID alias_sid;
        uint32 acc_granted;
+       SE_PRIV se_rights;
+       BOOL can_add_accounts;
+       BOOL ret;
 
        DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
 
@@ -3901,8 +4007,23 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S
                
        DEBUG(10, ("lookup on Local SID\n"));
 
+       se_priv_copy( &se_rights, &se_add_users );
+       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+       /******** BEGIN SeAddUsers BLOCK *********/
+       
+       if ( can_add_accounts )
+               become_root();
+
        /* Have passdb delete the alias */
-       if (!pdb_delete_alias(&alias_sid))
+       ret = pdb_delete_alias(&alias_sid);
+       
+       if ( can_add_accounts )
+               unbecome_root();
+               
+       /******** END SeAddUsers BLOCK *********/
+
+       if ( !ret )
                return NT_STATUS_ACCESS_DENIED;
 
        if (!close_policy_hnd(p, &q_u->alias_pol))
@@ -3925,6 +4046,9 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
        struct samr_info *info;
        uint32 acc_granted;
        gid_t gid;
+       SE_PRIV se_rights;
+       BOOL can_add_accounts;
+       NTSTATUS result;
 
        /* Find the policy handle. Open a policy on it. */
        if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
@@ -3937,32 +4061,53 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
        if (!sid_equal(&dom_sid, get_global_sam_sid()))
                return NT_STATUS_ACCESS_DENIED;
 
-       /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
-
        unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
 
        /* check if group already exist */
        if ((grp=getgrnam(name)) != NULL)
                return NT_STATUS_GROUP_EXISTS;
 
-       /* we can create the UNIX group */
-       if (smb_create_group(name, &gid) != 0)
-               return NT_STATUS_ACCESS_DENIED;
-
-       /* check if the group has been successfully created */
-       if ((grp=getgrgid(gid)) == NULL)
-               return NT_STATUS_ACCESS_DENIED;
+       se_priv_copy( &se_rights, &se_add_users );
+       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
 
-       r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
-
-       /* add the group to the mapping table */
-       sid_copy(&info_sid, get_global_sam_sid());
-       sid_append_rid(&info_sid, r_u->rid);
-       sid_to_string(sid_string, &info_sid);
+       /******** BEGIN SeAddUsers BLOCK *********/
+       
+       if ( can_add_accounts )
+               become_root();
+       
+       /* check that we successfully create the UNIX group */
+       
+       result = NT_STATUS_ACCESS_DENIED;
+       if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
+       
+               /* so far, so good */
+               
+               result = NT_STATUS_OK;
+               
+               r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
 
-       if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
-               return NT_STATUS_ACCESS_DENIED;
+               /* add the group to the mapping table */
+               
+               sid_copy( &info_sid, get_global_sam_sid() );
+               sid_append_rid( &info_sid, r_u->rid );
+               sid_to_string( sid_string, &info_sid );
+               
+               /* reset the error code if we fail to add the mapping entry */
+               
+               if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
+                       result = NT_STATUS_ACCESS_DENIED;
+       }
 
+       if ( can_add_accounts )
+               unbecome_root();
+               
+       /******** END SeAddUsers BLOCK *********/
+       
+       /* check if we should bail out here */
+       
+       if ( !NT_STATUS_IS_OK(result) )
+               return result;
+       
        if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
                return NT_STATUS_NO_MEMORY;
 
@@ -3987,6 +4132,8 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
        uint32 acc_granted;
        gid_t gid;
        NTSTATUS result;
+       SE_PRIV se_rights;
+       BOOL can_add_accounts;
 
        /* Find the policy handle. Open a policy on it. */
        if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
@@ -3999,13 +4146,24 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
        if (!sid_equal(&dom_sid, get_global_sam_sid()))
                return NT_STATUS_ACCESS_DENIED;
 
-       /* TODO: check if allowed to create group  and add a become_root/unbecome_root pair.*/
-
        unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
 
+       se_priv_copy( &se_rights, &se_add_users );
+       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+       /******** BEGIN SeAddUsers BLOCK *********/
+       
+       if ( can_add_accounts )
+               become_root();
+
        /* Have passdb create the alias */
        result = pdb_create_alias(name, &r_u->rid);
 
+       if ( can_add_accounts )
+               unbecome_root();
+               
+       /******** END SeAddUsers BLOCK *********/
+
        if (!NT_STATUS_IS_OK(result))
                return result;
 
index d5652b824765cd8c6f941c202ae624ab60509610..feb50b457a8a0f45ca4460bbc081fe7cd609dfe5 100644 (file)
 /********************************************************************
 ********************************************************************/
 
+static NTSTATUS sid_to_name(struct cli_state *cli, 
+                           TALLOC_CTX *mem_ctx,
+                           DOM_SID *sid, fstring name)
+{
+       POLICY_HND pol;
+       uint32 *sid_types;
+       NTSTATUS result;
+       char **domains, **names;
+
+       result = cli_lsa_open_policy(cli, mem_ctx, True, 
+               SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
+               
+       if ( !NT_STATUS_IS_OK(result) )
+               return result;
+
+       result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, 1, sid, &domains, &names, &sid_types);
+       
+       if ( NT_STATUS_IS_OK(result) ) {
+               if ( *domains[0] )
+                       fstr_sprintf( name, "%s\\%s", domains[0], names[0] );
+               else
+                       fstrcpy( name, names[0] );
+       }
+
+       cli_lsa_close(cli, mem_ctx, &pol);
+       return result;
+}
+
+/********************************************************************
+********************************************************************/
+
 static NTSTATUS name_to_sid(struct cli_state *cli, 
                            TALLOC_CTX *mem_ctx,
                            DOM_SID *sid, const char *name)
@@ -41,20 +72,14 @@ static NTSTATUS name_to_sid(struct cli_state *cli,
        result = cli_lsa_open_policy(cli, mem_ctx, True, 
                SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
                
-       if (!NT_STATUS_IS_OK(result))
+       if ( !NT_STATUS_IS_OK(result) )
                return result;
 
        result = cli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types);
        
-       if (!NT_STATUS_IS_OK(result)) {
-               d_printf("Failed to convert \"%s\" to a SID [%s]\n",
-                       name, nt_errstr(result));
-               goto done;
-       }
+       if ( NT_STATUS_IS_OK(result) )
+               sid_copy( sid, &sids[0] );
 
-       sid_copy( sid, &sids[0] );
-
-done:
        cli_lsa_close(cli, mem_ctx, &pol);
        return result;
 }
@@ -143,6 +168,7 @@ static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state
        DOM_SID *sids;
        uint32 count=0;
        int i;
+       fstring name;
 
        result = cli_lsa_enum_sids(cli, ctx, pol, &enum_context, 
                pref_max_length, &count, &sids);
@@ -151,8 +177,16 @@ static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state
                return result;
                
        for ( i=0; i<count; i++ ) {
-
-               d_printf("%s\n", sid_string_static(&sids[i]));
+       
+               /* try to convert the SID to a name.  Fall back to 
+                  printing the raw SID if necessary */
+                  
+               result = sid_to_name( cli, ctx, &sids[i], name );
+               if ( !NT_STATUS_IS_OK (result) )
+                       fstrcpy( name, sid_string_static(&sids[i]) );
+                       
+               d_printf("%s\n", name);
+               
                result = enum_privileges_for_user( ctx, cli, pol, &sids[i] );
                
                if ( !NT_STATUS_IS_OK(result) )
index 5d67c8fc7cf96e283f60d795a781da29fdbb8323..3665647905d9aac9bf8152529e1bc46bc87e7d9f 100644 (file)
@@ -34,7 +34,7 @@
 static char *netbiosname;
 static char packet[BUFFER_SIZE];
 
-static void save_file(const char *fname, void *packet, size_t length)
+static void save_file(const char *fname, void *ppacket, size_t length)
 {
        int fd;
        fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
@@ -42,7 +42,7 @@ static void save_file(const char *fname, void *packet, size_t length)
                perror(fname);
                return;
        }
-       if (write(fd, packet, length) != length) {
+       if (write(fd, ppacket, length) != length) {
                fprintf(stderr,"Failed to write %s\n", fname);
                return;
        }