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