LCOV - code coverage report
Current view: top level - source3/passdb - secrets.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 45 230 19.6 %
Date: 2024-06-13 04:01:37 Functions: 8 20 40.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Copyright (C) Andrew Tridgell 1992-2001
       4             :    Copyright (C) Andrew Bartlett      2002
       5             :    Copyright (C) Rafal Szczesniak     2002
       6             :    Copyright (C) Tim Potter           2001
       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             : /* the Samba secrets database stores any generated, private information
      23             :    such as the local SID and machine trust password */
      24             : 
      25             : #include "includes.h"
      26             : #include "system/filesys.h"
      27             : #include "../libcli/auth/libcli_auth.h"
      28             : #include "librpc/gen_ndr/ndr_secrets.h"
      29             : #include "secrets.h"
      30             : #include "dbwrap/dbwrap.h"
      31             : #include "dbwrap/dbwrap_open.h"
      32             : #include "../libcli/security/security.h"
      33             : #include "util_tdb.h"
      34             : #include "auth/credentials/credentials.h"
      35             : 
      36             : #undef DBGC_CLASS
      37             : #define DBGC_CLASS DBGC_PASSDB
      38             : 
      39             : static struct db_context *db_ctx;
      40             : 
      41             : /* open up the secrets database with specified private_dir path */
      42      111768 : bool secrets_init_path(const char *private_dir)
      43             : {
      44      111768 :         char *fname = NULL;
      45             :         TALLOC_CTX *frame;
      46             : 
      47      111768 :         if (db_ctx != NULL) {
      48       97373 :                 return True;
      49             :         }
      50             : 
      51       14395 :         if (private_dir == NULL) {
      52           0 :                 return False;
      53             :         }
      54             : 
      55       14395 :         frame = talloc_stackframe();
      56       14395 :         fname = talloc_asprintf(frame, "%s/secrets.tdb", private_dir);
      57       14395 :         if (fname == NULL) {
      58           0 :                 TALLOC_FREE(frame);
      59           0 :                 return False;
      60             :         }
      61             : 
      62       14395 :         db_ctx = db_open(NULL, fname, 0,
      63             :                          TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
      64             :                          DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
      65             : 
      66       14395 :         if (db_ctx == NULL) {
      67           0 :                 DEBUG(0,("Failed to open %s\n", fname));
      68           0 :                 TALLOC_FREE(frame);
      69           0 :                 return False;
      70             :         }
      71             : 
      72       14395 :         TALLOC_FREE(frame);
      73       14395 :         return True;
      74             : }
      75             : 
      76             : /* open up the secrets database */
      77       68673 : bool secrets_init(void)
      78             : {
      79       68673 :         return secrets_init_path(lp_private_dir());
      80             : }
      81             : 
      82       44297 : struct db_context *secrets_db_ctx(void)
      83             : {
      84       44297 :         if (!secrets_init()) {
      85           0 :                 return NULL;
      86             :         }
      87             : 
      88       44297 :         return db_ctx;
      89             : }
      90             : 
      91             : /*
      92             :  * close secrets.tdb
      93             :  */
      94         225 : void secrets_shutdown(void)
      95             : {
      96         225 :         TALLOC_FREE(db_ctx);
      97         225 : }
      98             : 
      99             : /* read a entry from the secrets database - the caller must free the result
     100             :    if size is non-null then the size of the entry is put in there
     101             :  */
     102       18521 : void *secrets_fetch(const char *key, size_t *size)
     103             : {
     104             :         TDB_DATA dbuf;
     105             :         void *result;
     106             :         NTSTATUS status;
     107             : 
     108       18521 :         if (!secrets_init()) {
     109           0 :                 return NULL;
     110             :         }
     111             : 
     112       18521 :         status = dbwrap_fetch(db_ctx, talloc_tos(), string_tdb_data(key),
     113             :                               &dbuf);
     114       18521 :         if (!NT_STATUS_IS_OK(status)) {
     115         772 :                 return NULL;
     116             :         }
     117             : 
     118       17749 :         result = smb_memdup(dbuf.dptr, dbuf.dsize);
     119       17749 :         if (result == NULL) {
     120           0 :                 return NULL;
     121             :         }
     122       17749 :         TALLOC_FREE(dbuf.dptr);
     123             : 
     124       17749 :         if (size) {
     125       14200 :                 *size = dbuf.dsize;
     126             :         }
     127             : 
     128       17749 :         return result;
     129             : }
     130             : 
     131             : /* store a secrets entry
     132             :  */
     133        1436 : bool secrets_store(const char *key, const void *data, size_t size)
     134             : {
     135             :         NTSTATUS status;
     136             : 
     137        1436 :         if (!secrets_init()) {
     138           0 :                 return false;
     139             :         }
     140             : 
     141        1436 :         status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
     142             :                                     make_tdb_data((const uint8_t *)data, size),
     143             :                                     TDB_REPLACE);
     144        1436 :         return NT_STATUS_IS_OK(status);
     145             : }
     146             : 
     147           0 : bool secrets_store_creds(struct cli_credentials *creds)
     148             : {
     149           0 :         const char *p = NULL;
     150             :         bool ok;
     151             : 
     152           0 :         p = cli_credentials_get_username(creds);
     153           0 :         if (p == NULL) {
     154           0 :                 return false;
     155             :         }
     156             : 
     157           0 :         ok = secrets_store(SECRETS_AUTH_USER, p, strlen(p) + 1);
     158           0 :         if (!ok) {
     159           0 :                 DBG_ERR("Failed storing auth user name\n");
     160           0 :                 return false;
     161             :         }
     162             : 
     163             : 
     164           0 :         p = cli_credentials_get_domain(creds);
     165           0 :         if (p == NULL) {
     166           0 :                 return false;
     167             :         }
     168             : 
     169           0 :         ok = secrets_store(SECRETS_AUTH_DOMAIN, p, strlen(p) + 1);
     170           0 :         if (!ok) {
     171           0 :                 DBG_ERR("Failed storing auth domain name\n");
     172           0 :                 return false;
     173             :         }
     174             : 
     175             : 
     176           0 :         p = cli_credentials_get_password(creds);
     177           0 :         if (p == NULL) {
     178           0 :                 return false;
     179             :         }
     180             : 
     181           0 :         ok = secrets_store(SECRETS_AUTH_PASSWORD, p, strlen(p) + 1);
     182           0 :         if (!ok) {
     183           0 :                 DBG_ERR("Failed storing auth password\n");
     184           0 :                 return false;
     185             :         }
     186             : 
     187           0 :         return true;
     188             : }
     189             : 
     190             : 
     191             : /* delete a secets database entry
     192             :  */
     193          92 : bool secrets_delete_entry(const char *key)
     194             : {
     195             :         NTSTATUS status;
     196          92 :         if (!secrets_init()) {
     197           0 :                 return false;
     198             :         }
     199             : 
     200          92 :         status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
     201             : 
     202          92 :         return NT_STATUS_IS_OK(status);
     203             : }
     204             : 
     205             : /*
     206             :  * Deletes the key if it exists.
     207             :  */
     208         406 : bool secrets_delete(const char *key)
     209             : {
     210             :         bool exists;
     211             : 
     212         406 :         if (!secrets_init()) {
     213           0 :                 return false;
     214             :         }
     215             : 
     216         406 :         exists = dbwrap_exists(db_ctx, string_tdb_data(key));
     217         406 :         if (!exists) {
     218         353 :                 return true;
     219             :         }
     220             : 
     221          53 :         return secrets_delete_entry(key);
     222             : }
     223             : 
     224             : /**
     225             :  * Form a key for fetching a trusted domain password
     226             :  *
     227             :  * @param domain trusted domain name
     228             :  *
     229             :  * @return stored password's key
     230             :  **/
     231           0 : static char *trustdom_keystr(const char *domain)
     232             : {
     233             :         char *keystr;
     234             : 
     235           0 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
     236             :                                             SECRETS_DOMTRUST_ACCT_PASS,
     237             :                                             domain);
     238           0 :         SMB_ASSERT(keystr != NULL);
     239           0 :         return keystr;
     240             : }
     241             : 
     242             : /************************************************************************
     243             :  Routine to get account password to trusted domain
     244             : ************************************************************************/
     245             : 
     246           0 : bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
     247             :                                            struct dom_sid *sid, time_t *pass_last_set_time)
     248             : {
     249             :         struct TRUSTED_DOM_PASS pass;
     250             :         enum ndr_err_code ndr_err;
     251             : 
     252             :         /* unpacking structures */
     253             :         DATA_BLOB blob;
     254             : 
     255             :         /* fetching trusted domain password structure */
     256           0 :         if (!(blob.data = (uint8_t *)secrets_fetch(trustdom_keystr(domain),
     257             :                                                    &blob.length))) {
     258           0 :                 DEBUG(5, ("secrets_fetch failed!\n"));
     259           0 :                 return False;
     260             :         }
     261             : 
     262             :         /* unpack trusted domain password */
     263           0 :         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
     264             :                         (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
     265             : 
     266           0 :         SAFE_FREE(blob.data);
     267             : 
     268           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     269           0 :                 return false;
     270             :         }
     271             : 
     272             : 
     273             :         /* the trust's password */
     274           0 :         if (pwd) {
     275           0 :                 *pwd = SMB_STRDUP(pass.pass);
     276           0 :                 if (!*pwd) {
     277           0 :                         return False;
     278             :                 }
     279             :         }
     280             : 
     281             :         /* last change time */
     282           0 :         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
     283             : 
     284             :         /* domain sid */
     285           0 :         if (sid != NULL) sid_copy(sid, &pass.domain_sid);
     286             : 
     287           0 :         return True;
     288             : }
     289             : 
     290             : /**
     291             :  * Routine to store the password for trusted domain
     292             :  *
     293             :  * @param domain remote domain name
     294             :  * @param pwd plain text password of trust relationship
     295             :  * @param sid remote domain sid
     296             :  *
     297             :  * @return true if succeeded
     298             :  **/
     299             : 
     300           0 : bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
     301             :                                            const struct dom_sid *sid)
     302             : {
     303             :         bool ret;
     304             : 
     305             :         /* packing structures */
     306             :         DATA_BLOB blob;
     307             :         enum ndr_err_code ndr_err;
     308             :         struct TRUSTED_DOM_PASS pass;
     309           0 :         ZERO_STRUCT(pass);
     310             : 
     311           0 :         pass.uni_name = domain;
     312           0 :         pass.uni_name_len = strlen(domain)+1;
     313             : 
     314             :         /* last change time */
     315           0 :         pass.mod_time = time(NULL);
     316             : 
     317             :         /* password of the trust */
     318           0 :         pass.pass_len = strlen(pwd);
     319           0 :         pass.pass = pwd;
     320             : 
     321             :         /* domain sid */
     322           0 :         sid_copy(&pass.domain_sid, sid);
     323             : 
     324           0 :         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &pass,
     325             :                         (ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS);
     326           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     327           0 :                 return false;
     328             :         }
     329             : 
     330           0 :         ret = secrets_store(trustdom_keystr(domain), blob.data, blob.length);
     331             : 
     332           0 :         data_blob_free(&blob);
     333             : 
     334           0 :         return ret;
     335             : }
     336             : 
     337             : /************************************************************************
     338             :  Routine to delete the password for trusted domain
     339             : ************************************************************************/
     340             : 
     341           0 : bool trusted_domain_password_delete(const char *domain)
     342             : {
     343           0 :         return secrets_delete_entry(trustdom_keystr(domain));
     344             : }
     345             : 
     346           0 : bool secrets_store_ldap_pw(const char* dn, char* pw)
     347             : {
     348           0 :         char *key = NULL;
     349             :         bool ret;
     350             : 
     351           0 :         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
     352           0 :                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
     353           0 :                 return False;
     354             :         }
     355             : 
     356           0 :         ret = secrets_store(key, pw, strlen(pw)+1);
     357             : 
     358           0 :         SAFE_FREE(key);
     359           0 :         return ret;
     360             : }
     361             : 
     362             : /*******************************************************************
     363             :  Find the ldap password.
     364             : ******************************************************************/
     365             : 
     366           0 : bool fetch_ldap_pw(char **dn, char** pw)
     367             : {
     368           0 :         char *key = NULL;
     369           0 :         size_t size = 0;
     370             : 
     371           0 :         *dn = smb_xstrdup(lp_ldap_admin_dn());
     372             : 
     373           0 :         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
     374           0 :                 SAFE_FREE(*dn);
     375           0 :                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
     376           0 :                 return false;
     377             :         }
     378             : 
     379           0 :         *pw=(char *)secrets_fetch(key, &size);
     380           0 :         SAFE_FREE(key);
     381             : 
     382           0 :         if ((size != 0) && ((*pw)[size-1] != '\0')) {
     383           0 :                 DBG_ERR("Non 0-terminated password for dn %s\n", *dn);
     384           0 :                 SAFE_FREE(*pw);
     385           0 :                 SAFE_FREE(*dn);
     386           0 :                 return false;
     387             :         }
     388             : 
     389           0 :         if (!size) {
     390             :                 /* Upgrade 2.2 style entry */
     391             :                 char *p;
     392           0 :                 char* old_style_key = SMB_STRDUP(*dn);
     393             :                 char *data;
     394             :                 fstring old_style_pw;
     395             : 
     396           0 :                 if (!old_style_key) {
     397           0 :                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
     398           0 :                         SAFE_FREE(*pw);
     399           0 :                         SAFE_FREE(*dn);
     400           0 :                         return False;
     401             :                 }
     402             : 
     403           0 :                 for (p=old_style_key; *p; p++)
     404           0 :                         if (*p == ',') *p = '/';
     405             : 
     406           0 :                 data=(char *)secrets_fetch(old_style_key, &size);
     407           0 :                 if ((data == NULL) || (size < sizeof(old_style_pw))) {
     408           0 :                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
     409           0 :                         SAFE_FREE(old_style_key);
     410           0 :                         SAFE_FREE(*pw);
     411           0 :                         SAFE_FREE(*dn);
     412           0 :                         SAFE_FREE(data);
     413           0 :                         return False;
     414             :                 }
     415             : 
     416           0 :                 size = MIN(size, sizeof(fstring)-1);
     417           0 :                 strncpy(old_style_pw, data, size);
     418           0 :                 old_style_pw[size] = 0;
     419             : 
     420           0 :                 SAFE_FREE(data);
     421             : 
     422           0 :                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
     423           0 :                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
     424           0 :                         SAFE_FREE(old_style_key);
     425           0 :                         SAFE_FREE(*pw);
     426           0 :                         SAFE_FREE(*dn);
     427           0 :                         return False;
     428             :                 }
     429           0 :                 if (!secrets_delete_entry(old_style_key)) {
     430           0 :                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
     431             :                 }
     432             : 
     433           0 :                 SAFE_FREE(old_style_key);
     434             : 
     435           0 :                 *pw = smb_xstrdup(old_style_pw);
     436             :         }
     437             : 
     438           0 :         return True;
     439             : }
     440             : 
     441             : /*******************************************************************************
     442             :  Store a complete AFS keyfile into secrets.tdb.
     443             : *******************************************************************************/
     444             : 
     445           0 : bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
     446             : {
     447             :         fstring key;
     448             : 
     449           0 :         if ((cell == NULL) || (keyfile == NULL))
     450           0 :                 return False;
     451             : 
     452           0 :         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
     453           0 :                 return False;
     454             : 
     455           0 :         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
     456           0 :         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
     457             : }
     458             : 
     459             : /*******************************************************************************
     460             :  Fetch the current (highest) AFS key from secrets.tdb
     461             : *******************************************************************************/
     462           0 : bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
     463             : {
     464             :         fstring key;
     465             :         struct afs_keyfile *keyfile;
     466           0 :         size_t size = 0;
     467             :         uint32_t i;
     468             : 
     469           0 :         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
     470             : 
     471           0 :         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
     472             : 
     473           0 :         if (keyfile == NULL)
     474           0 :                 return False;
     475             : 
     476           0 :         if (size != sizeof(struct afs_keyfile)) {
     477           0 :                 SAFE_FREE(keyfile);
     478           0 :                 return False;
     479             :         }
     480             : 
     481           0 :         i = ntohl(keyfile->nkeys);
     482             : 
     483           0 :         if (i > SECRETS_AFS_MAXKEYS) {
     484           0 :                 SAFE_FREE(keyfile);
     485           0 :                 return False;
     486             :         }
     487             : 
     488           0 :         *result = keyfile->entry[i-1];
     489             : 
     490           0 :         result->kvno = ntohl(result->kvno);
     491             : 
     492           0 :         SAFE_FREE(keyfile);
     493             : 
     494           0 :         return True;
     495             : }
     496             : 
     497             : /******************************************************************************
     498             :   When kerberos is not available, choose between anonymous or
     499             :   authenticated connections.
     500             : 
     501             :   We need to use an authenticated connection if DCs have the
     502             :   RestrictAnonymous registry entry set > 0, or the "Additional
     503             :   restrictions for anonymous connections" set in the win2k Local
     504             :   Security Policy.
     505             : 
     506             :   Caller to free() result in domain, username, password
     507             : *******************************************************************************/
     508           0 : void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
     509             : {
     510           0 :         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
     511           0 :         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
     512           0 :         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
     513             : 
     514           0 :         if (*username && **username) {
     515             : 
     516           0 :                 if (!*domain || !**domain)
     517           0 :                         *domain = smb_xstrdup(lp_workgroup());
     518             : 
     519           0 :                 if (!*password || !**password)
     520           0 :                         *password = smb_xstrdup("");
     521             : 
     522           0 :                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
     523             :                           *domain, *username));
     524             : 
     525             :         } else {
     526           0 :                 DEBUG(3, ("IPC$ connections done anonymously\n"));
     527           0 :                 *username = smb_xstrdup("");
     528           0 :                 *domain = smb_xstrdup("");
     529           0 :                 *password = smb_xstrdup("");
     530             :         }
     531           0 : }
     532             : 
     533           0 : bool secrets_store_generic(const char *owner, const char *key, const char *secret)
     534             : {
     535           0 :         char *tdbkey = NULL;
     536             :         bool ret;
     537             : 
     538           0 :         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
     539           0 :                 DEBUG(0, ("asprintf failed!\n"));
     540           0 :                 return False;
     541             :         }
     542             : 
     543           0 :         ret = secrets_store(tdbkey, secret, strlen(secret)+1);
     544             : 
     545           0 :         SAFE_FREE(tdbkey);
     546           0 :         return ret;
     547             : }
     548             : 
     549             : /*******************************************************************
     550             :  Find the ldap password.
     551             : ******************************************************************/
     552             : 
     553           0 : char *secrets_fetch_generic(const char *owner, const char *key)
     554             : {
     555           0 :         char *secret = NULL;
     556           0 :         char *tdbkey = NULL;
     557             : 
     558           0 :         if (( ! owner) || ( ! key)) {
     559           0 :                 DEBUG(1, ("Invalid Parameters"));
     560           0 :                 return NULL;
     561             :         }
     562             : 
     563           0 :         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
     564           0 :                 DEBUG(0, ("Out of memory!\n"));
     565           0 :                 return NULL;
     566             :         }
     567             : 
     568           0 :         secret = (char *)secrets_fetch(tdbkey, NULL);
     569           0 :         SAFE_FREE(tdbkey);
     570             : 
     571           0 :         return secret;
     572             : }
     573             : 

Generated by: LCOV version 1.13