1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* 3 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved 4 * 5 * $Header$ 6 */ 7 8 #include "k5-int.h" 9 10 #include <sys/file.h> 11 #include "policy_db.h" 12 13 #define OPENLOCK(db, mode) \ 14 { \ 15 int olret; \ 16 if (db == NULL) \ 17 return EINVAL; \ 18 else if (db->magic != OSA_ADB_POLICY_DB_MAGIC) \ 19 return OSA_ADB_DBINIT; \ 20 else if ((olret = osa_adb_open_and_lock(db, mode)) != OSA_ADB_OK) \ 21 return olret; \ 22 } 23 24 #define CLOSELOCK(db) \ 25 { \ 26 int cl_ret; \ 27 if ((cl_ret = osa_adb_close_and_unlock(db)) != OSA_ADB_OK) \ 28 return cl_ret; \ 29 } 30 31 32 /* 33 * Function: osa_adb_create_policy 34 * 35 * Purpose: create a policy entry in the policy db. 36 * 37 * Arguments: 38 * entry (input) pointer to the entry to be added 39 * <return value> OSA_ADB_OK on success, else error code. 40 * 41 * Requires: 42 * entry have a valid name. 43 * 44 * Effects: 45 * creates the entry in the db 46 * 47 * Modifies: 48 * the policy db. 49 * 50 */ 51 krb5_error_code 52 osa_adb_create_policy(osa_adb_policy_t db, osa_policy_ent_t entry) 53 { 54 DBT dbkey; 55 DBT dbdata; 56 XDR xdrs; 57 int ret; 58 59 OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); 60 61 if(entry->name == NULL) { 62 ret = EINVAL; 63 goto error; 64 } 65 dbkey.data = entry->name; 66 dbkey.size = (strlen(entry->name) + 1); 67 68 switch(db->db->get(db->db, &dbkey, &dbdata, 0)) { 69 case 0: 70 ret = OSA_ADB_DUP; 71 goto error; 72 case 1: 73 break; 74 default: 75 ret = errno; 76 goto error; 77 } 78 xdralloc_create(&xdrs, XDR_ENCODE); 79 if(!xdr_osa_policy_ent_rec(&xdrs, entry)) { 80 xdr_destroy(&xdrs); 81 ret = OSA_ADB_XDR_FAILURE; 82 goto error; 83 } 84 dbdata.data = xdralloc_getdata(&xdrs); 85 dbdata.size = xdr_getpos(&xdrs); 86 switch(db->db->put(db->db, &dbkey, &dbdata, R_NOOVERWRITE)) { 87 case 0: 88 if((db->db->sync(db->db, 0)) == -1) 89 ret = OSA_ADB_FAILURE; 90 ret = OSA_ADB_OK; 91 break; 92 case 1: 93 ret = OSA_ADB_DUP; 94 break; 95 default: 96 ret = OSA_ADB_FAILURE; 97 break; 98 } 99 xdr_destroy(&xdrs); 100 101 error: 102 CLOSELOCK(db); 103 return ret; 104 } 105 106 /* 107 * Function: osa_adb_destroy_policy 108 * 109 * Purpose: destroy a policy entry 110 * 111 * Arguments: 112 * db (input) database handle 113 * name (input) name of policy 114 * <return value> OSA_ADB_OK on success, or error code. 115 * 116 * Requires: 117 * db being valid. 118 * name being non-null. 119 * Effects: 120 * deletes policy from db. 121 * 122 * Modifies: 123 * policy db. 124 * 125 */ 126 krb5_error_code 127 osa_adb_destroy_policy(osa_adb_policy_t db, char *name) 128 { 129 DBT dbkey; 130 int status, ret; 131 132 OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); 133 134 if(name == NULL) { 135 ret = EINVAL; 136 goto error; 137 } 138 dbkey.data = name; 139 dbkey.size = (strlen(name) + 1); 140 141 status = db->db->del(db->db, &dbkey, 0); 142 switch(status) { 143 case 1: 144 ret = OSA_ADB_NOENT; 145 goto error; 146 case 0: 147 if ((db->db->sync(db->db, 0)) == -1) { 148 ret = OSA_ADB_FAILURE; 149 goto error; 150 } 151 ret = OSA_ADB_OK; 152 break; 153 default: 154 ret = OSA_ADB_FAILURE; 155 goto error; 156 } 157 158 error: 159 CLOSELOCK(db); 160 return ret; 161 } 162 163 /* 164 * Function: osa_adb_get_policy 165 * 166 * Purpose: retrieve policy 167 * 168 * Arguments: 169 * db (input) db handle 170 * name (input) name of policy 171 * entry (output) policy entry 172 * cnt (inout) Number of entries 173 * <return value> 0 on success, error code on failure. 174 * 175 * Requires: 176 * Effects: 177 * Modifies: 178 */ 179 krb5_error_code 180 osa_adb_get_policy(osa_adb_policy_t db, char *name, 181 osa_policy_ent_t *entry_ptr) 182 { 183 DBT dbkey; 184 DBT dbdata; 185 XDR xdrs; 186 int ret; 187 char *aligned_data = NULL; 188 osa_policy_ent_t entry = NULL; 189 190 *entry_ptr = NULL; 191 OPENLOCK(db, KRB5_DB_LOCKMODE_SHARED); 192 193 if(name == NULL) { 194 ret = EINVAL; 195 goto error; 196 } 197 dbkey.data = name; 198 dbkey.size = (strlen(dbkey.data) + 1); 199 dbdata.data = NULL; 200 dbdata.size = 0; 201 switch((db->db->get(db->db, &dbkey, &dbdata, 0))) { 202 case 1: 203 ret = KRB5_KDB_NOENTRY; 204 goto error; 205 case 0: 206 break; 207 default: 208 ret = OSA_ADB_FAILURE; 209 goto error; 210 } 211 entry = k5alloc(sizeof(*entry), &ret); 212 if (entry == NULL) 213 goto error; 214 aligned_data = k5memdup(dbdata.data, dbdata.size, &ret); 215 if (aligned_data == NULL) 216 goto error; 217 xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE); 218 if (!xdr_osa_policy_ent_rec(&xdrs, entry)) { 219 ret = OSA_ADB_FAILURE; 220 goto error; 221 } 222 ret = OSA_ADB_OK; 223 xdr_destroy(&xdrs); 224 *entry_ptr = entry; 225 entry = NULL; 226 227 error: 228 free(aligned_data); 229 free(entry); 230 CLOSELOCK(db); 231 return ret; 232 } 233 234 /* 235 * Function: osa_adb_put_policy 236 * 237 * Purpose: update a policy in the dababase 238 * 239 * Arguments: 240 * db (input) db handle 241 * entry (input) policy entry 242 * <return value> 0 on success error code on failure. 243 * 244 * Requires: 245 * [requires] 246 * 247 * Effects: 248 * [effects] 249 * 250 * Modifies: 251 * [modifies] 252 * 253 */ 254 krb5_error_code 255 osa_adb_put_policy(osa_adb_policy_t db, osa_policy_ent_t entry) 256 { 257 DBT dbkey; 258 DBT dbdata; 259 DBT tmpdb; 260 XDR xdrs; 261 int ret; 262 263 OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); 264 265 if(entry->name == NULL) { 266 ret = EINVAL; 267 goto error; 268 } 269 dbkey.data = entry->name; 270 dbkey.size = (strlen(entry->name) + 1); 271 switch(db->db->get(db->db, &dbkey, &tmpdb, 0)) { 272 case 0: 273 break; 274 case 1: 275 ret = OSA_ADB_NOENT; 276 goto error; 277 default: 278 ret = OSA_ADB_FAILURE; 279 goto error; 280 } 281 xdralloc_create(&xdrs, XDR_ENCODE); 282 if(!xdr_osa_policy_ent_rec(&xdrs, entry)) { 283 xdr_destroy(&xdrs); 284 ret = OSA_ADB_XDR_FAILURE; 285 goto error; 286 } 287 dbdata.data = xdralloc_getdata(&xdrs); 288 dbdata.size = xdr_getpos(&xdrs); 289 switch(db->db->put(db->db, &dbkey, &dbdata, 0)) { 290 case 0: 291 if((db->db->sync(db->db, 0)) == -1) 292 ret = OSA_ADB_FAILURE; 293 ret = OSA_ADB_OK; 294 break; 295 default: 296 ret = OSA_ADB_FAILURE; 297 break; 298 } 299 xdr_destroy(&xdrs); 300 301 error: 302 CLOSELOCK(db); 303 return ret; 304 } 305 306 /* 307 * Function: osa_adb_iter_policy 308 * 309 * Purpose: iterate over the policy database. 310 * 311 * Arguments: 312 * db (input) db handle 313 * func (input) function pointer to call 314 * data opaque data type 315 * <return value> 0 on success error code on failure 316 * 317 * Requires: 318 * Effects: 319 * Modifies: 320 */ 321 krb5_error_code 322 osa_adb_iter_policy(osa_adb_policy_t db, osa_adb_iter_policy_func func, 323 void *data) 324 { 325 DBT dbkey, 326 dbdata; 327 XDR xdrs; 328 int ret; 329 osa_policy_ent_t entry; 330 char *aligned_data; 331 332 OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); /* hmmm */ 333 334 if((ret = db->db->seq(db->db, &dbkey, &dbdata, R_FIRST)) == -1) { 335 ret = errno; 336 goto error; 337 } 338 339 while (ret == 0) { 340 entry = k5alloc(sizeof(osa_policy_ent_rec), &ret); 341 if (entry == NULL) 342 goto error; 343 344 aligned_data = k5memdup(dbdata.data, dbdata.size, &ret); 345 if (aligned_data == NULL) { 346 free(entry); 347 goto error; 348 } 349 350 xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE); 351 if(!xdr_osa_policy_ent_rec(&xdrs, entry)) { 352 xdr_destroy(&xdrs); 353 free(aligned_data); 354 osa_free_policy_ent(entry); 355 ret = OSA_ADB_FAILURE; 356 goto error; 357 } 358 (*func)(data, entry); 359 xdr_destroy(&xdrs); 360 free(aligned_data); 361 osa_free_policy_ent(entry); 362 ret = db->db->seq(db->db, &dbkey, &dbdata, R_NEXT); 363 } 364 if(ret == -1) 365 ret = errno; 366 else ret = OSA_ADB_OK; 367 368 error: 369 CLOSELOCK(db); 370 return ret; 371 } 372 373 void 374 osa_free_policy_ent(osa_policy_ent_t val) 375 { 376 XDR xdrs; 377 378 xdrmem_create(&xdrs, NULL, 0, XDR_FREE); 379 380 xdr_osa_policy_ent_rec(&xdrs, val); 381 382 free(val); 383 } 384