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