r1198: Merge the Samba 3.0 ntlm_auth, including the kerberos and SPENGO parts.
[kai/samba.git] / source / passdb / secrets.c
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    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_PASSDB
29
30 static TDB_CONTEXT *tdb;
31
32 /* open up the secrets database */
33 BOOL secrets_init(void)
34 {
35         pstring fname;
36
37         if (tdb)
38                 return True;
39
40         pstrcpy(fname, lp_private_dir());
41         pstrcat(fname,"/secrets.tdb");
42
43         tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
44
45         if (!tdb) {
46                 DEBUG(0,("Failed to open %s\n", fname));
47                 return False;
48         }
49         return True;
50 }
51
52 /* read a entry from the secrets database - the caller must free the result
53    if size is non-null then the size of the entry is put in there
54  */
55 static void *secrets_fetch(const char *key, size_t *size)
56 {
57         TDB_DATA kbuf, dbuf;
58         secrets_init();
59         if (!tdb)
60                 return NULL;
61         kbuf.dptr = strdup(key);
62         kbuf.dsize = strlen(key);
63         dbuf = tdb_fetch(tdb, kbuf);
64         if (size)
65                 *size = dbuf.dsize;
66         free(kbuf.dptr);
67         return dbuf.dptr;
68 }
69
70 /************************************************************************
71  Routine to fetch the plaintext machine account password for a realm
72 the password is assumed to be a null terminated ascii string
73 ************************************************************************/
74 char *secrets_fetch_machine_password(const char *domain)
75 {
76         char *key;
77         char *ret;
78         asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
79         strupper(key);
80         ret = (char *)secrets_fetch(key, NULL);
81         free(key);
82         return ret;
83 }
84
85
86
87 /*******************************************************************************
88  Lock the secrets tdb based on a string - this is used as a primitive form of mutex
89  between smbd instances.
90 *******************************************************************************/
91
92 BOOL secrets_named_mutex(const char *name, uint_t timeout, size_t *p_ref_count)
93 {
94         size_t ref_count = *p_ref_count;
95         int ret = 0;
96
97         if (!message_init())
98                 return False;
99
100         if (ref_count == 0) {
101                 ret = tdb_lock_bystring(tdb, name, timeout);
102                 if (ret == 0)
103                         DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
104         }
105
106         if (ret == 0) {
107                 *p_ref_count = ++ref_count;
108                 DEBUG(10,("secrets_named_mutex: ref_count for mutex %s = %u\n", name, (uint_t)ref_count ));
109         }
110         return (ret == 0);
111 }
112
113 /*******************************************************************************
114  Unlock a named mutex.
115 *******************************************************************************/
116
117 void secrets_named_mutex_release(const char *name, size_t *p_ref_count)
118 {
119         size_t ref_count = *p_ref_count;
120
121         SMB_ASSERT(ref_count != 0);
122
123         if (ref_count == 1) {
124                 tdb_unlock_bystring(tdb, name);
125                 DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
126         }
127
128         *p_ref_count = --ref_count;
129         DEBUG(10,("secrets_named_mutex_release: ref_count for mutex %s = %u\n", name, (uint_t)ref_count ));
130 }
131