Annotation of libaitcfg/src/pq.c, revision 1.2
1.2 ! misho 1: /*************************************************************************
! 2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
! 3: * by Michael Pounov <misho@openbsd-bg.org>
! 4: *
! 5: * $Author: misho $
! 6: * $Id: pq.c,v 1.1.2.11 2012/09/19 14:07:20 misho Exp $
! 7: *
! 8: **************************************************************************
! 9: The ELWIX and AITNET software is distributed under the following
! 10: terms:
! 11:
! 12: All of the documentation and software included in the ELWIX and AITNET
! 13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
! 14:
! 15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
! 16: by Michael Pounov <misho@elwix.org>. All rights reserved.
! 17:
! 18: Redistribution and use in source and binary forms, with or without
! 19: modification, are permitted provided that the following conditions
! 20: are met:
! 21: 1. Redistributions of source code must retain the above copyright
! 22: notice, this list of conditions and the following disclaimer.
! 23: 2. Redistributions in binary form must reproduce the above copyright
! 24: notice, this list of conditions and the following disclaimer in the
! 25: documentation and/or other materials provided with the distribution.
! 26: 3. All advertising materials mentioning features or use of this software
! 27: must display the following acknowledgement:
! 28: This product includes software developed by Michael Pounov <misho@elwix.org>
! 29: ELWIX - Embedded LightWeight unIX and its contributors.
! 30: 4. Neither the name of AITNET nor the names of its contributors
! 31: may be used to endorse or promote products derived from this software
! 32: without specific prior written permission.
! 33:
! 34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
! 35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 44: SUCH DAMAGE.
! 45: */
! 46: #include "global.h"
! 47:
! 48:
! 49: static inline struct tagUser *
! 50: _selectPasswd(pwd_root_t * __restrict pwd, u_int uid, const char *csName)
! 51: {
! 52: struct tagUser fu;
! 53:
! 54: if (!pwd)
! 55: return NULL;
! 56: else
! 57: memset(&fu, 0, sizeof fu);
! 58:
! 59: if (csName) {
! 60: io_setlikeVar(&fu.usr_name, string, strlen(csName) + 1, csName);
! 61: return RB_FIND(tagPWD, pwd, &fu);
! 62: }
! 63:
! 64: return (struct tagUser*) cfg_findPasswdBy(pwd, PWD_CRIT_UID, uid);
! 65: }
! 66:
! 67: /* --------------------------------------------------------------- */
! 68:
! 69: /*
! 70: * cfg_findPasswdBy() - Find user by criteria position in list
! 71: *
! 72: * @pwd = Password root
! 73: * @criteria = Search criteria [PWD_CRIT_NAME|PWD_CRIT_UID|PWD_CRIT_GID]
! 74: * @arg1 = Username | UID | GID
! 75: * return: NULL not found item or error and !=NULL found item
! 76: */
! 77: const struct tagUser *
! 78: cfg_findPasswdBy(pwd_root_t * __restrict pwd, int criteria, ...)
! 79: {
! 80: struct tagUser *u;
! 81: va_list lst;
! 82: ait_val_t v;
! 83:
! 84: if (!pwd)
! 85: return NULL;
! 86: else
! 87: AIT_INIT_VAL(&v);
! 88:
! 89: va_start(lst, criteria);
! 90: switch (criteria) {
! 91: case PWD_CRIT_NAME:
! 92: AIT_SET_STR(&v, va_arg(lst, char*));
! 93: break;
! 94: case PWD_CRIT_UID:
! 95: case PWD_CRIT_GID:
! 96: AIT_SET_U32(&v, va_arg(lst, u_int));
! 97: break;
! 98: default:
! 99: return NULL;
! 100: }
! 101: va_end(lst);
! 102:
! 103: SLIST_FOREACH(u, pwd, usr_next)
! 104: switch (criteria) {
! 105: case PWD_CRIT_NAME:
! 106: if (!io_cmpVar(&u->usr_name, &v)) {
! 107: AIT_FREE_VAL(&v);
! 108: return u;
! 109: }
! 110: break;
! 111: case PWD_CRIT_UID:
! 112: if ((u_int) AIT_RAW(&u->usr_uid) == AIT_GET_U32(&v)) {
! 113: AIT_FREE_VAL(&v);
! 114: return u;
! 115: }
! 116: break;
! 117: case PWD_CRIT_GID:
! 118: if ((u_int) AIT_RAW(&u->usr_gid) == AIT_GET_U32(&v)) {
! 119: AIT_FREE_VAL(&v);
! 120: return u;
! 121: }
! 122: break;
! 123: }
! 124:
! 125: AIT_FREE_VAL(&v);
! 126: return NULL;
! 127: }
! 128:
! 129: /*
! 130: * cfg_unsetPasswd() - Unset item from passwords and free resources
! 131: *
! 132: * @pwd = Password root
! 133: * @criteria = Search criteria [PWD_CRIT_NAME|PWD_CRIT_UID]
! 134: * @arg1 = Username | UID
! 135: * return: 0 item not found, -1 error or 1 removed item
! 136: */
! 137: int
! 138: cfg_unsetPasswd(pwd_root_t * __restrict pwd, int criteria, ...)
! 139: {
! 140: struct tagUser *u, *u2;
! 141: va_list lst;
! 142: u_int n = 0;
! 143: char *name = NULL;
! 144:
! 145: if (!pwd)
! 146: return -1;
! 147:
! 148: va_start(lst, criteria);
! 149: switch (criteria) {
! 150: case PWD_CRIT_UID:
! 151: n = va_arg(lst, u_int);
! 152: break;
! 153: case PWD_CRIT_NAME:
! 154: name = va_arg(lst, char*);
! 155: if (name)
! 156: break;
! 157: default:
! 158: va_end(lst);
! 159: return -1;
! 160: }
! 161: va_end(lst);
! 162:
! 163: u = _selectPasswd(pwd, n, name);
! 164: if (!u)
! 165: return 0;
! 166:
! 167: PWD_LOCK(pwd);
! 168: RB_REMOVE(tagPWD, pwd, u);
! 169: SLIST_REMOVE(pwd, u, tagUser, usr_next);
! 170:
! 171: /* if duplicates exists, then update r/b tree */
! 172: SLIST_FOREACH(u2, pwd, usr_next)
! 173: if (!AIT_ISEMPTY(&u2->usr_name) &&
! 174: !strcmp(AIT_GET_STR(&u->usr_name), AIT_GET_STR(&u2->usr_name))) {
! 175: RB_INSERT(tagPWD, pwd, u2);
! 176: break;
! 177: }
! 178: PWD_UNLOCK(pwd);
! 179:
! 180: AIT_FREE_VAL(&u->usr_name);
! 181: AIT_FREE_VAL(&u->usr_pass);
! 182: AIT_FREE_VAL(&u->usr_uid);
! 183: AIT_FREE_VAL(&u->usr_gid);
! 184: AIT_FREE_VAL(&u->usr_class);
! 185: AIT_FREE_VAL(&u->usr_change);
! 186: AIT_FREE_VAL(&u->usr_expire);
! 187: AIT_FREE_VAL(&u->usr_realm);
! 188: AIT_FREE_VAL(&u->usr_home);
! 189: AIT_FREE_VAL(&u->usr_shell);
! 190: io_free(u);
! 191: return 1;
! 192: }
! 193:
! 194: /*
! 195: * cfg_setPasswd() - Set item in password or adding new item if not exists
! 196: *
! 197: * @cfg = Password root
! 198: * @fields = Meaning continuous field
! 199: * @csName = Username
! 200: * @arg1 = Password
! 201: * @arg2 = UID
! 202: * @arg3 = GID
! 203: * @arg4 = Login class
! 204: * @arg5 = Chage date
! 205: * @arg6 = Expire date
! 206: * @arg7 = Realm
! 207: * @arg8 = Home dir
! 208: * @arg9 = Shell
! 209: * return: 0 nothing changed, -1 error, 1 found and updated item or 2 added new item
! 210: */
! 211: int
! 212: cfg_setPasswd(pwd_root_t * __restrict pwd, u_char fields, const char *csName, ...)
! 213: {
! 214: struct tagUser *u;
! 215: register int i;
! 216: va_list lst;
! 217:
! 218: if (!pwd || !csName)
! 219: return -1;
! 220:
! 221: u = _selectPasswd(pwd, 0, csName);
! 222: if (!u) {
! 223: /* adding new element */
! 224: u = io_malloc(sizeof(struct tagUser));
! 225: if (!u) {
! 226: cfg_SetErr(io_GetErrno(), "%s", io_GetError());
! 227: return -1;
! 228: } else {
! 229: memset(u, 0, sizeof(struct tagUser));
! 230: if (fields && fields < PWD_MAX_FIELDS)
! 231: u->usr_fields = fields;
! 232: else
! 233: u->usr_fields = PWD_MAX_FIELDS - 1;
! 234:
! 235: PWD_LOCK(pwd);
! 236: SLIST_INSERT_HEAD(pwd, u, usr_next);
! 237: PWD_UNLOCK(pwd);
! 238: }
! 239:
! 240: va_start(lst, csName);
! 241: for (i = 0; i < (u->usr_fields + 1); i++)
! 242: switch (i) {
! 243: case 0:
! 244: AIT_SET_STR(&u->usr_name, csName);
! 245: break;
! 246: case 1:
! 247: AIT_SET_STR(&u->usr_pass, va_arg(lst, char*));
! 248: break;
! 249: case 2:
! 250: AIT_SET_U32(&u->usr_uid, va_arg(lst, u_int));
! 251: break;
! 252: case 3:
! 253: AIT_SET_U32(&u->usr_gid, va_arg(lst, u_int));
! 254: break;
! 255: case 4:
! 256: AIT_SET_STR(&u->usr_class, va_arg(lst, char*));
! 257: break;
! 258: case 5:
! 259: AIT_SET_U32(&u->usr_change, va_arg(lst, u_int));
! 260: break;
! 261: case 6:
! 262: AIT_SET_U32(&u->usr_expire, va_arg(lst, u_int));
! 263: break;
! 264: case 7:
! 265: AIT_SET_STR(&u->usr_realm, va_arg(lst, char*));
! 266: break;
! 267: case 8:
! 268: AIT_SET_STR(&u->usr_home, va_arg(lst, char*));
! 269: break;
! 270: case 9:
! 271: AIT_SET_STR(&u->usr_shell, va_arg(lst, char*));
! 272: break;
! 273: }
! 274: va_end(lst);
! 275:
! 276: AIT_KEY(&u->usr_name) = crcFletcher16(AIT_GET_LIKE(&u->usr_name, u_short*),
! 277: io_align(AIT_LEN(&u->usr_name) - 1, 2) / 2);
! 278:
! 279: PWD_LOCK(pwd);
! 280: RB_INSERT(tagPWD, pwd, u);
! 281: PWD_UNLOCK(pwd);
! 282: return 2;
! 283: } else {
! 284: AIT_FREE_VAL(&u->usr_pass);
! 285: AIT_FREE_VAL(&u->usr_uid);
! 286: AIT_FREE_VAL(&u->usr_gid);
! 287: AIT_FREE_VAL(&u->usr_class);
! 288: AIT_FREE_VAL(&u->usr_change);
! 289: AIT_FREE_VAL(&u->usr_expire);
! 290: AIT_FREE_VAL(&u->usr_realm);
! 291: AIT_FREE_VAL(&u->usr_home);
! 292: AIT_FREE_VAL(&u->usr_shell);
! 293:
! 294: /* Update element */
! 295: va_start(lst, csName);
! 296: for (i = 1; i < (u->usr_fields + 1); i++)
! 297: switch (i) {
! 298: case 1:
! 299: AIT_SET_STR(&u->usr_pass, va_arg(lst, char*));
! 300: break;
! 301: case 2:
! 302: AIT_SET_U32(&u->usr_uid, va_arg(lst, u_int));
! 303: break;
! 304: case 3:
! 305: AIT_SET_U32(&u->usr_gid, va_arg(lst, u_int));
! 306: break;
! 307: case 4:
! 308: AIT_SET_STR(&u->usr_class, va_arg(lst, char*));
! 309: break;
! 310: case 5:
! 311: AIT_SET_U32(&u->usr_change, va_arg(lst, u_int));
! 312: break;
! 313: case 6:
! 314: AIT_SET_U32(&u->usr_expire, va_arg(lst, u_int));
! 315: break;
! 316: case 7:
! 317: AIT_SET_STR(&u->usr_realm, va_arg(lst, char*));
! 318: break;
! 319: case 8:
! 320: AIT_SET_STR(&u->usr_home, va_arg(lst, char*));
! 321: break;
! 322: case 9:
! 323: AIT_SET_STR(&u->usr_shell, va_arg(lst, char*));
! 324: break;
! 325: }
! 326: va_end(lst);
! 327: return 1;
! 328: }
! 329:
! 330: /* Nothing happens ... found & values is equal! */
! 331: return 0;
! 332: }
! 333:
! 334: /*
! 335: * cfg_getPasswd() - Get item from passwords and return structure from it
! 336: *
! 337: * @pwd = Password root
! 338: * @criteria = Search criteria [PWD_CRIT_NAME|PWD_CRIT_UID]
! 339: * @arg1 = Username | UID
! 340: * return: NULL item not found, !=NULL structure found
! 341: */
! 342: inline const struct tagUser *
! 343: cfg_getPasswd(pwd_root_t * __restrict pwd, int criteria, ...)
! 344: {
! 345: struct tagUser *u;
! 346: va_list lst;
! 347: char *str;
! 348:
! 349: if (!pwd)
! 350: return NULL;
! 351:
! 352: va_start(lst, criteria);
! 353: switch (criteria) {
! 354: case PWD_CRIT_NAME:
! 355: str = va_arg(lst, char*);
! 356: if (!str)
! 357: u = NULL;
! 358: else
! 359: u = _selectPasswd(pwd, 0, str);
! 360: break;
! 361: case PWD_CRIT_UID:
! 362: u = _selectPasswd(pwd, va_arg(lst, u_int), NULL);
! 363: break;
! 364: default:
! 365: u = NULL;
! 366: break;
! 367: }
! 368: va_end(lst);
! 369:
! 370: return u;
! 371: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>