Removed version number from file header.
[kai/samba.git] / source3 / passdb / secrets.c
index 9591474861a8d652c49b714ac15e68bf177fa62f..89f67cb5b7de9d0c27889ffe69c3539aa4354083 100644 (file)
@@ -1,8 +1,6 @@
 /* 
-   Unix SMB/Netbios implementation.
-   Version 3.0.
-   Samba registry functions
-   Copyright (C) Andrew Tridgell 1992-1998
+   Unix SMB/CIFS implementation.
+   Copyright (C) Andrew Tridgell 1992-2001
    
    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
@@ -31,12 +29,13 @@ BOOL secrets_init(void)
 {
        pstring fname;
 
-       if (tdb) return True;
+       if (tdb)
+               return True;
 
        pstrcpy(fname, lp_private_dir());
        pstrcat(fname,"/secrets.tdb");
 
-       tdb = tdb_open(fname, 0, 0, O_RDWR|O_CREAT, 0600);
+       tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
 
        if (!tdb) {
                DEBUG(0,("Failed to open %s\n", fname));
@@ -51,11 +50,14 @@ BOOL secrets_init(void)
 void *secrets_fetch(char *key, size_t *size)
 {
        TDB_DATA kbuf, dbuf;
-       if (!tdb) return False;
+       secrets_init();
+       if (!tdb)
+               return NULL;
        kbuf.dptr = key;
        kbuf.dsize = strlen(key);
        dbuf = tdb_fetch(tdb, kbuf);
-       if (size) *size = dbuf.dsize;
+       if (size)
+               *size = dbuf.dsize;
        return dbuf.dptr;
 }
 
@@ -64,7 +66,9 @@ void *secrets_fetch(char *key, size_t *size)
 BOOL secrets_store(char *key, void *data, size_t size)
 {
        TDB_DATA kbuf, dbuf;
-       if (!tdb) return False;
+       secrets_init();
+       if (!tdb)
+               return False;
        kbuf.dptr = key;
        kbuf.dsize = strlen(key);
        dbuf.dptr = data;
@@ -78,7 +82,9 @@ BOOL secrets_store(char *key, void *data, size_t size)
 BOOL secrets_delete(char *key)
 {
        TDB_DATA kbuf;
-       if (!tdb) return False;
+       secrets_init();
+       if (!tdb)
+               return False;
        kbuf.dptr = key;
        kbuf.dsize = strlen(key);
        return tdb_delete(tdb, kbuf) == 0;
@@ -88,7 +94,7 @@ BOOL secrets_store_domain_sid(char *domain, DOM_SID *sid)
 {
        fstring key;
 
-       slprintf(key, sizeof(key), "%s/%s", SECRETS_DOMAIN_SID, domain);
+       slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
        return secrets_store(key, sid, sizeof(DOM_SID));
 }
 
@@ -98,8 +104,7 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
        fstring key;
        size_t size;
 
-       slprintf(key, sizeof(key), "%s/%s", SECRETS_DOMAIN_SID, domain);
-       dos_to_unix(key, True);                /* Convert key to unix-codepage */
+       slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
        dyn_sid = (DOM_SID *)secrets_fetch(key, &size);
 
        if (dyn_sid == NULL)
@@ -107,12 +112,12 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
 
        if (size != sizeof(DOM_SID))
        { 
-               free(dyn_sid);
+               SAFE_FREE(dyn_sid);
                return False;
        }
 
        *sid = *dyn_sid;
-       free(dyn_sid);
+       SAFE_FREE(dyn_sid);
        return True;
 }
 
@@ -123,27 +128,45 @@ form a key for fetching a domain trust password
 char *trust_keystr(char *domain)
 {
        static fstring keystr;
-       slprintf(keystr,sizeof(keystr),"%s/%s", SECRETS_MACHINE_ACCT_PASS, domain);
-       dos_to_unix(keystr, True);         /* Convert key to unix-codepage */
+
+       slprintf(keystr,sizeof(keystr)-1,"%s/%s", 
+                SECRETS_MACHINE_ACCT_PASS, domain);
+
        return keystr;
 }
 
 /************************************************************************
  Routine to get the trust account password for a domain.
- The user of this function must have locked the trust password file.
 ************************************************************************/
 BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16],
                                          time_t *pass_last_set_time)
 {
        struct machine_acct_pass *pass;
+       char *plaintext;
        size_t size;
 
-       if (!(pass = secrets_fetch(trust_keystr(domain), &size)) || size != sizeof(*pass))
+       plaintext = secrets_fetch_machine_password();
+       if (plaintext) {
+               /* we have an ADS password - use that */
+               DEBUG(4,("Using ADS machine password\n"));
+               E_md4hash((uchar *)plaintext, ret_pwd);
+               SAFE_FREE(plaintext);
+               return True;
+       }
+
+       if (!(pass = secrets_fetch(trust_keystr(domain), &size))) {
+               DEBUG(5, ("secrets_fetch failed!\n"));
                return False;
+       }
+       
+       if (size != sizeof(*pass)) {
+               DEBUG(0, ("secrets were of incorrect size!\n"));
+               return False;
+       }
 
        if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
        memcpy(ret_pwd, pass->hash, 16);
-       free(pass);
+       SAFE_FREE(pass);
        return True;
 }
 
@@ -161,6 +184,27 @@ BOOL secrets_store_trust_account_password(char *domain, uint8 new_pwd[16])
        return secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass));
 }
 
+/************************************************************************
+ Routine to set the plaintext machine account password for a realm
+the password is assumed to be a null terminated ascii string
+************************************************************************/
+BOOL secrets_store_machine_password(char *pass)
+{
+       return secrets_store(SECRETS_MACHINE_PASSWORD, pass, strlen(pass)+1);
+}
+
+
+/************************************************************************
+ Routine to fetch the plaintext machine account password for a realm
+the password is assumed to be a null terminated ascii string
+************************************************************************/
+char *secrets_fetch_machine_password(void)
+{
+       return (char *)secrets_fetch(SECRETS_MACHINE_PASSWORD, NULL);
+}
+
+
+
 /************************************************************************
  Routine to delete the trust account password file for a domain.
 ************************************************************************/
@@ -169,3 +213,75 @@ BOOL trust_password_delete(char *domain)
 {
        return secrets_delete(trust_keystr(domain));
 }
+
+/*******************************************************************
+ Reset the 'done' variables so after a client process is created
+ from a fork call these calls will be re-done. This should be
+ expanded if more variables need reseting.
+ ******************************************************************/
+
+void reset_globals_after_fork(void)
+{
+       unsigned char dummy;
+
+       secrets_init();
+
+       /*
+        * Increment the global seed value to ensure every smbd starts
+        * with a new random seed.
+        */
+
+       if (tdb) {
+               uint32 initial_val = sys_getpid();
+               tdb_change_int32_atomic(tdb, "INFO/random_seed", (int *)&initial_val, 1);
+               set_rand_reseed_data((unsigned char *)&initial_val, sizeof(initial_val));
+       }
+
+       /*
+        * Re-seed the random crypto generator, so all smbd's
+        * started from the same parent won't generate the same
+        * sequence.
+        */
+       generate_random_buffer( &dummy, 1, True);
+}
+
+BOOL secrets_store_ldap_pw(char* dn, char* pw)
+{
+       fstring key;
+       char *p;
+       
+       pstrcpy(key, dn);
+       for (p=key; *p; p++)
+               if (*p == ',') *p = '/';
+       
+       return secrets_store(key, pw, strlen(pw));
+}
+
+BOOL fetch_ldap_pw(char *dn, char* pw, int len)
+{
+       fstring key;
+       char *p;
+       void *data = NULL;
+       size_t size;
+       
+       pstrcpy(key, dn);
+       for (p=key; *p; p++)
+               if (*p == ',') *p = '/';
+       
+       data=secrets_fetch(key, &size);
+       if (!size) {
+               DEBUG(0,("fetch_ldap_pw: no ldap secret retrieved!\n"));
+               return False;
+       }
+       
+       if (size > len-1)
+       {
+               DEBUG(0,("fetch_ldap_pw: ldap secret is too long (%d > %d)!\n", size, len-1));
+               return False;
+       }
+
+       memcpy(pw, data, size);
+       pw[size] = '\0';
+       
+       return True;
+}