LCOV - code coverage report
Current view: top level - source3/passdb - account_pol.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 100 197 50.8 %
Date: 2024-04-21 15:09:00 Functions: 9 13 69.2 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  account policy storage
       4             :  *  Copyright (C) Jean François Micouleau      1998-2001
       5             :  *  Copyright (C) Andrew Bartlett              2002
       6             :  *  Copyright (C) Guenther Deschner            2004-2005
       7             :  *
       8             :  *  This program is free software; you can redistribute it and/or modify
       9             :  *  it under the terms of the GNU General Public License as published by
      10             :  *  the Free Software Foundation; either version 3 of the License, or
      11             :  *  (at your option) any later version.
      12             :  *
      13             :  *  This program is distributed in the hope that it will be useful,
      14             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  *  GNU General Public License for more details.
      17             :  *
      18             :  *  You should have received a copy of the GNU General Public License
      19             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include "includes.h"
      23             : #include "system/filesys.h"
      24             : #include "passdb.h"
      25             : #include "dbwrap/dbwrap.h"
      26             : #include "dbwrap/dbwrap_open.h"
      27             : #include "../libcli/security/security.h"
      28             : #include "lib/privileges.h"
      29             : #include "lib/gencache.h"
      30             : #include "lib/util/smb_strtox.h"
      31             : 
      32             : static struct db_context *db;
      33             : 
      34             : /* cache all entries for 60 seconds for to save ldap-queries (cache is updated
      35             :  * after this period if admins do not use pdbedit or usermanager but manipulate
      36             :  * ldap directly) - gd */
      37             : 
      38             : #define DATABASE_VERSION        3
      39             : #define AP_TTL                  60
      40             : 
      41             : 
      42             : struct ap_table {
      43             :         enum pdb_policy_type type;
      44             :         const char *string;
      45             :         uint32_t default_val;
      46             :         const char *description;
      47             :         const char *ldap_attr;
      48             : };
      49             : 
      50             : static const struct ap_table account_policy_names[] = {
      51             :         {PDB_POLICY_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH,
      52             :                 "Minimal password length (default: 5)",
      53             :                 "sambaMinPwdLength" },
      54             : 
      55             :         {PDB_POLICY_PASSWORD_HISTORY, "password history", 0,
      56             :                 "Length of Password History Entries (default: 0 => off)",
      57             :                 "sambaPwdHistoryLength" },
      58             : 
      59             :         {PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
      60             :                 "Force Users to logon for password change (default: 0 => off, 2 => on)",
      61             :                 "sambaLogonToChgPwd" },
      62             : 
      63             :         {PDB_POLICY_MAX_PASSWORD_AGE, "maximum password age", (uint32_t) -1,
      64             :                 "Maximum password age, in seconds (default: -1 => never expire passwords)",
      65             :                 "sambaMaxPwdAge" },
      66             : 
      67             :         {PDB_POLICY_MIN_PASSWORD_AGE,"minimum password age", 0,
      68             :                 "Minimal password age, in seconds (default: 0 => allow immediate password change)",
      69             :                 "sambaMinPwdAge" },
      70             : 
      71             :         {PDB_POLICY_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
      72             :                 "Lockout duration in minutes (default: 30, -1 => forever)",
      73             :                 "sambaLockoutDuration" },
      74             : 
      75             :         {PDB_POLICY_RESET_COUNT_TIME, "reset count minutes", 30,
      76             :                 "Reset time after lockout in minutes (default: 30)",
      77             :                 "sambaLockoutObservationWindow" },
      78             : 
      79             :         {PDB_POLICY_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
      80             :                 "Lockout users after bad logon attempts (default: 0 => off)",
      81             :                 "sambaLockoutThreshold" },
      82             : 
      83             :         {PDB_POLICY_TIME_TO_LOGOUT, "disconnect time", (uint32_t) -1,
      84             :                 "Disconnect Users outside logon hours (default: -1 => off, 0 => on)",
      85             :                 "sambaForceLogoff" },
      86             : 
      87             :         {PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
      88             :                 "Allow Machine Password changes (default: 0 => off)",
      89             :                 "sambaRefuseMachinePwdChange" },
      90             : 
      91             :         {0, NULL, 0, "", NULL}
      92             : };
      93             : 
      94           4 : void account_policy_names_list(TALLOC_CTX *mem_ctx, const char ***names, int *num_names)
      95             : {
      96           4 :         const char **nl;
      97           4 :         int i, count = ARRAY_SIZE(account_policy_names);
      98             : 
      99           4 :         nl = talloc_array(mem_ctx, const char *, count);
     100           4 :         if (!nl) {
     101           0 :                 *num_names = 0;
     102           0 :                 return;
     103             :         }
     104          48 :         for (i=0; i<count; i++) {
     105          44 :                 nl[i] = account_policy_names[i].string;
     106             :         }
     107             :         /* Do not return the last null entry */
     108           4 :         *num_names = count-1;
     109           4 :         *names = nl;
     110           4 :         return;
     111             : }
     112             : 
     113             : /****************************************************************************
     114             : Get the account policy name as a string from its #define'ed number
     115             : ****************************************************************************/
     116             : 
     117      246581 : const char *decode_account_policy_name(enum pdb_policy_type type)
     118             : {
     119         134 :         int i;
     120      731656 :         for (i=0; account_policy_names[i].string; i++) {
     121      731656 :                 if (type == account_policy_names[i].type) {
     122      246581 :                         return account_policy_names[i].string;
     123             :                 }
     124             :         }
     125           0 :         return NULL;
     126             : }
     127             : 
     128             : /****************************************************************************
     129             : Get the account policy LDAP attribute as a string from its #define'ed number
     130             : ****************************************************************************/
     131             : 
     132           0 : const char *get_account_policy_attr(enum pdb_policy_type type)
     133             : {
     134           0 :         int i;
     135           0 :         for (i=0; account_policy_names[i].type; i++) {
     136           0 :                 if (type == account_policy_names[i].type) {
     137           0 :                         return account_policy_names[i].ldap_attr;
     138             :                 }
     139             :         }
     140           0 :         return NULL;
     141             : }
     142             : 
     143             : /****************************************************************************
     144             : Get the account policy description as a string from its #define'ed number
     145             : ****************************************************************************/
     146             : 
     147           0 : const char *account_policy_get_desc(enum pdb_policy_type type)
     148             : {
     149           0 :         int i;
     150           0 :         for (i=0; account_policy_names[i].string; i++) {
     151           0 :                 if (type == account_policy_names[i].type) {
     152           0 :                         return account_policy_names[i].description;
     153             :                 }
     154             :         }
     155           0 :         return NULL;
     156             : }
     157             : 
     158             : /****************************************************************************
     159             : Get the account policy name as a string from its #define'ed number
     160             : ****************************************************************************/
     161             : 
     162          40 : enum pdb_policy_type account_policy_name_to_typenum(const char *name)
     163             : {
     164          40 :         int i;
     165         220 :         for (i=0; account_policy_names[i].string; i++) {
     166         220 :                 if (strcmp(name, account_policy_names[i].string) == 0) {
     167          40 :                         return account_policy_names[i].type;
     168             :                 }
     169             :         }
     170           0 :         return 0;
     171             : }
     172             : 
     173             : /*****************************************************************************
     174             : Get default value for account policy
     175             : *****************************************************************************/
     176             : 
     177         970 : bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val)
     178             : {
     179           0 :         int i;
     180        5335 :         for (i=0; account_policy_names[i].type; i++) {
     181        5335 :                 if (account_policy_names[i].type == type) {
     182         970 :                         *val = account_policy_names[i].default_val;
     183         970 :                         return True;
     184             :                 }
     185             :         }
     186           0 :         DEBUG(0,("no default for account_policy index %d found. This should never happen\n",
     187             :                 type));
     188           0 :         return False;
     189             : }
     190             : 
     191             : /*****************************************************************************
     192             :  Set default for a type if it is empty
     193             : *****************************************************************************/
     194             : 
     195         990 : static bool account_policy_set_default_on_empty(enum pdb_policy_type type)
     196             : {
     197             : 
     198          20 :         uint32_t value;
     199             : 
     200         990 :         if (!account_policy_get(type, &value) &&
     201         970 :             !account_policy_get_default(type, &value)) {
     202           0 :                 return False;
     203             :         }
     204             : 
     205         990 :         return account_policy_set(type, value);
     206             : }
     207             : 
     208             : /*****************************************************************************
     209             :  Open the account policy tdb.
     210             : ***`*************************************************************************/
     211             : 
     212      278950 : bool init_account_policy(void)
     213             : {
     214             : 
     215      278950 :         const char *vstring = "INFO/version";
     216      278950 :         uint32_t version = 0;
     217         976 :         int i;
     218         976 :         NTSTATUS status;
     219         976 :         char *db_path;
     220             : 
     221      278950 :         if (db != NULL) {
     222      276622 :                 return True;
     223             :         }
     224             : 
     225        1356 :         db_path = state_path(talloc_tos(), "account_policy.tdb");
     226        1356 :         if (db_path == NULL) {
     227           0 :                 return false;
     228             :         }
     229             : 
     230        1356 :         db = db_open(NULL, db_path, 0, TDB_DEFAULT,
     231             :                      O_RDWR, 0600, DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
     232             : 
     233        1356 :         if (db == NULL) { /* the account policies files does not exist or open
     234             :                            * failed, try to create a new one */
     235          97 :                 db = db_open(NULL, db_path, 0,
     236             :                              TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
     237             :                              DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
     238          97 :                 if (db == NULL) {
     239           0 :                         DEBUG(0,("Failed to open account policy database\n"));
     240           0 :                         TALLOC_FREE(db_path);
     241           0 :                         return False;
     242             :                 }
     243             :         }
     244        1356 :         TALLOC_FREE(db_path);
     245             : 
     246        1356 :         status = dbwrap_fetch_uint32_bystring(db, vstring, &version);
     247        1356 :         if (!NT_STATUS_IS_OK(status)) {
     248          97 :                 version = 0;
     249             :         }
     250             : 
     251        1356 :         if (version == DATABASE_VERSION) {
     252        1255 :                 return true;
     253             :         }
     254             : 
     255             :         /* handle a Samba upgrade */
     256             : 
     257          99 :         if (dbwrap_transaction_start(db) != 0) {
     258           0 :                 DEBUG(0, ("transaction_start failed\n"));
     259           0 :                 TALLOC_FREE(db);
     260           0 :                 return false;
     261             :         }
     262             : 
     263          99 :         status = dbwrap_fetch_uint32_bystring(db, vstring, &version);
     264          99 :         if (!NT_STATUS_IS_OK(status)) {
     265          97 :                 version = 0;
     266             :         }
     267             : 
     268          99 :         if (version == DATABASE_VERSION) {
     269             :                 /*
     270             :                  * Race condition
     271             :                  */
     272           0 :                 if (dbwrap_transaction_cancel(db)) {
     273           0 :                         smb_panic("transaction_cancel failed");
     274             :                 }
     275           0 :                 return true;
     276             :         }
     277             : 
     278          99 :         if (version != DATABASE_VERSION) {
     279          99 :                 status = dbwrap_store_uint32_bystring(db, vstring,
     280             :                                                       DATABASE_VERSION);
     281          99 :                 if (!NT_STATUS_IS_OK(status)) {
     282           0 :                         DEBUG(0, ("dbwrap_store_uint32_t failed: %s\n",
     283             :                                   nt_errstr(status)));
     284           0 :                         goto cancel;
     285             :                 }
     286             : 
     287        1089 :                 for (i=0; account_policy_names[i].type; i++) {
     288             : 
     289         990 :                         if (!account_policy_set_default_on_empty(account_policy_names[i].type)) {
     290           0 :                                 DEBUG(0,("failed to set default value in account policy tdb\n"));
     291           0 :                                 goto cancel;
     292             :                         }
     293             :                 }
     294             :         }
     295             : 
     296             :         /* These exist by default on NT4 in [HKLM\SECURITY\Policy\Accounts] */
     297             : 
     298          99 :         privilege_create_account( &global_sid_World );
     299          99 :         privilege_create_account( &global_sid_Builtin_Account_Operators );
     300          99 :         privilege_create_account( &global_sid_Builtin_Server_Operators );
     301          99 :         privilege_create_account( &global_sid_Builtin_Print_Operators );
     302          99 :         privilege_create_account( &global_sid_Builtin_Backup_Operators );
     303             : 
     304             :         /* BUILTIN\Administrators get everything -- *always* */
     305             : 
     306          99 :         if ( lp_enable_privileges() ) {
     307          99 :                 if ( !grant_all_privileges( &global_sid_Builtin_Administrators ) ) {
     308           0 :                         DEBUG(1,("init_account_policy: Failed to grant privileges "
     309             :                                 "to BUILTIN\\Administrators!\n"));
     310             :                 }
     311             :         }
     312             : 
     313          99 :         if (dbwrap_transaction_commit(db) != 0) {
     314           0 :                 DEBUG(0, ("transaction_commit failed\n"));
     315           0 :                 TALLOC_FREE(db);
     316           0 :                 return false;
     317             :         }
     318             : 
     319          97 :         return True;
     320             : 
     321           0 :  cancel:
     322           0 :         if (dbwrap_transaction_cancel(db)) {
     323           0 :                 smb_panic("transaction_cancel failed");
     324             :         }
     325           0 :         TALLOC_FREE(db);
     326             : 
     327           0 :         return false;
     328             : }
     329             : 
     330             : /*****************************************************************************
     331             : Get an account policy (from tdb)
     332             : *****************************************************************************/
     333             : 
     334      245591 : bool account_policy_get(enum pdb_policy_type type, uint32_t *value)
     335             : {
     336         114 :         const char *name;
     337         114 :         uint32_t regval;
     338         114 :         NTSTATUS status;
     339             : 
     340      245591 :         if (!init_account_policy()) {
     341           0 :                 return False;
     342             :         }
     343             : 
     344      245591 :         if (value) {
     345      245591 :                 *value = 0;
     346             :         }
     347             : 
     348      245591 :         name = decode_account_policy_name(type);
     349      245591 :         if (name == NULL) {
     350           0 :                 DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type!  Cannot get, returning 0.\n", type));
     351           0 :                 return False;
     352             :         }
     353             : 
     354      245591 :         status = dbwrap_fetch_uint32_bystring(db, name, &regval);
     355      245591 :         if (!NT_STATUS_IS_OK(status)) {
     356         970 :                 DEBUG(2, ("account_policy_get: tdb_fetch_uint32_t failed for type %d (%s), returning 0\n", type, name));
     357         970 :                 return False;
     358             :         }
     359             : 
     360      244621 :         if (value) {
     361      244621 :                 *value = regval;
     362             :         }
     363             : 
     364      244621 :         DEBUG(10,("account_policy_get: name: %s, val: %d\n", name, regval));
     365      244507 :         return True;
     366             : }
     367             : 
     368             : 
     369             : /****************************************************************************
     370             : Set an account policy (in tdb)
     371             : ****************************************************************************/
     372             : 
     373         990 : bool account_policy_set(enum pdb_policy_type type, uint32_t value)
     374             : {
     375          20 :         const char *name;
     376          20 :         NTSTATUS status;
     377             : 
     378         990 :         if (!init_account_policy()) {
     379           0 :                 return False;
     380             :         }
     381             : 
     382         990 :         name = decode_account_policy_name(type);
     383         990 :         if (name == NULL) {
     384           0 :                 DEBUG(1, ("Field %d is not a valid account policy type!  Cannot set.\n", type));
     385           0 :                 return False;
     386             :         }
     387             : 
     388         990 :         status = dbwrap_trans_store_uint32_bystring(db, name, value);
     389         990 :         if (!NT_STATUS_IS_OK(status)) {
     390           0 :                 DEBUG(1, ("store_uint32_t failed for type %d (%s) on value "
     391             :                           "%u: %s\n", type, name, value, nt_errstr(status)));
     392           0 :                 return False;
     393             :         }
     394             : 
     395         990 :         DEBUG(10,("account_policy_set: name: %s, value: %d\n", name, value));
     396             : 
     397         970 :         return True;
     398             : }
     399             : 
     400             : /****************************************************************************
     401             : Set an account policy in the cache
     402             : ****************************************************************************/
     403             : 
     404           0 : bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value)
     405             : {
     406           0 :         const char *policy_name = NULL;
     407           0 :         char *cache_key = NULL;
     408           0 :         char *cache_value = NULL;
     409           0 :         bool ret = False;
     410             : 
     411           0 :         policy_name = decode_account_policy_name(type);
     412           0 :         if (policy_name == NULL) {
     413           0 :                 DEBUG(0,("cache_account_policy_set: no policy found\n"));
     414           0 :                 return False;
     415             :         }
     416             : 
     417           0 :         if (asprintf(&cache_key, "ACCT_POL/%s", policy_name) < 0) {
     418           0 :                 DEBUG(0, ("asprintf failed\n"));
     419           0 :                 goto done;
     420             :         }
     421             : 
     422           0 :         if (asprintf(&cache_value, "%lu\n", (unsigned long)value) < 0) {
     423           0 :                 DEBUG(0, ("asprintf failed\n"));
     424           0 :                 goto done;
     425             :         }
     426             : 
     427           0 :         DEBUG(10,("cache_account_policy_set: updating account pol cache\n"));
     428             : 
     429           0 :         ret = gencache_set(cache_key, cache_value, time(NULL)+AP_TTL);
     430             : 
     431           0 :  done:
     432           0 :         SAFE_FREE(cache_key);
     433           0 :         SAFE_FREE(cache_value);
     434           0 :         return ret;
     435             : }
     436             : 
     437             : /*****************************************************************************
     438             : Get an account policy from the cache
     439             : *****************************************************************************/
     440             : 
     441           0 : bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value)
     442             : {
     443           0 :         const char *policy_name = NULL;
     444           0 :         char *cache_key = NULL;
     445           0 :         char *cache_value = NULL;
     446           0 :         bool ret = False;
     447             : 
     448           0 :         policy_name = decode_account_policy_name(type);
     449           0 :         if (policy_name == NULL) {
     450           0 :                 DEBUG(0,("cache_account_policy_set: no policy found\n"));
     451           0 :                 return False;
     452             :         }
     453             : 
     454           0 :         if (asprintf(&cache_key, "ACCT_POL/%s", policy_name) < 0) {
     455           0 :                 DEBUG(0, ("asprintf failed\n"));
     456           0 :                 goto done;
     457             :         }
     458             : 
     459           0 :         if (gencache_get(cache_key, talloc_tos(), &cache_value, NULL)) {
     460           0 :                 int error = 0;
     461           0 :                 uint32_t tmp;
     462             : 
     463           0 :                 tmp = smb_strtoul(cache_value,
     464             :                                   NULL,
     465             :                                   10,
     466             :                                   &error,
     467             :                                   SMB_STR_STANDARD);
     468           0 :                 if (error != 0) {
     469           0 :                         goto done;
     470             :                 }
     471           0 :                 *value = tmp;
     472           0 :                 ret = True;
     473             :         }
     474             : 
     475           0 :  done:
     476           0 :         SAFE_FREE(cache_key);
     477           0 :         TALLOC_FREE(cache_value);
     478           0 :         return ret;
     479             : }
     480             : 
     481             : /****************************************************************************
     482             : ****************************************************************************/
     483             : 
     484      190793 : struct db_context *get_account_pol_db( void )
     485             : {
     486             : 
     487      190793 :         if ( db == NULL ) {
     488         806 :                 if ( !init_account_policy() ) {
     489           0 :                         return NULL;
     490             :                 }
     491             :         }
     492             : 
     493      190793 :         return db;
     494             : }

Generated by: LCOV version 1.14