Annotation of libaitcfg/src/pq.c, revision 1.1.2.8

1.1.2.1   misho       1: /*************************************************************************
                      2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
                      3: *  by Michael Pounov <misho@openbsd-bg.org>
                      4: *
                      5: * $Author: misho $
1.1.2.8 ! misho       6: * $Id: pq.c,v 1.1.2.7 2012/09/19 12:35:10 misho Exp $
1.1.2.1   misho       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 *
1.1.2.2   misho      50: _selectPasswd(pwd_root_t * __restrict pwd, u_int uid, const char *csName)
1.1.2.1   misho      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: 
1.1.2.3   misho      64:        return (struct tagUser*) cfg_findPasswdBy(pwd, PWD_CRIT_UID, uid);
1.1.2.1   misho      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:  */
1.1.2.3   misho      77: const struct tagUser *
1.1.2.1   misho      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;
1.1.2.6   misho      86:        else
                     87:                AIT_INIT_VAL(&v);
1.1.2.1   misho      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:
1.1.2.4   misho     112:                                if (AIT_GET_LIKE(&u->usr_uid, u_int) == AIT_GET_U32(&v)) {
1.1.2.1   misho     113:                                        AIT_FREE_VAL(&v);
                    114:                                        return u;
                    115:                                }
                    116:                                break;
                    117:                        case PWD_CRIT_GID:
1.1.2.4   misho     118:                                if (AIT_GET_LIKE(&u->usr_gid, u_int) == AIT_GET_U32(&v)) {
1.1.2.1   misho     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;
                    141:        va_list lst;
                    142: 
                    143:        if (!pwd)
                    144:                return -1;
                    145: 
                    146:        va_start(lst, criteria);
                    147:        switch (criteria) {
                    148:                case PWD_CRIT_NAME:
1.1.2.2   misho     149:                        u = _selectPasswd(pwd, 0, va_arg(lst, char*));
1.1.2.1   misho     150:                        break;
                    151:                case PWD_CRIT_UID:
1.1.2.2   misho     152:                        u = _selectPasswd(pwd, va_arg(lst, u_int), NULL);
1.1.2.1   misho     153:                        break;
                    154:                default:
                    155:                        va_end(lst);
                    156:                        return -1;
                    157:        }
                    158:        va_end(lst);
                    159:        if (!u)
                    160:                return 0;
                    161: 
                    162:        PWD_LOCK(pwd);
                    163:        RB_REMOVE(tagPWD, pwd, u);
                    164:        SLIST_REMOVE(pwd, u, tagUser, usr_next);
                    165:        PWD_UNLOCK(pwd);
                    166: 
                    167:        AIT_FREE_VAL(&u->usr_name);
                    168:        AIT_FREE_VAL(&u->usr_pass);
                    169:        AIT_FREE_VAL(&u->usr_uid);
                    170:        AIT_FREE_VAL(&u->usr_gid);
                    171:        AIT_FREE_VAL(&u->usr_class);
                    172:        AIT_FREE_VAL(&u->usr_change);
                    173:        AIT_FREE_VAL(&u->usr_expire);
                    174:        AIT_FREE_VAL(&u->usr_realm);
                    175:        AIT_FREE_VAL(&u->usr_home);
                    176:        AIT_FREE_VAL(&u->usr_shell);
                    177:        io_free(u);
                    178:        return 1;
                    179: }
                    180: 
                    181: /*
1.1.2.2   misho     182:  * cfg_setPasswd() - Set item in password or adding new item if not exists
1.1.2.1   misho     183:  *
1.1.2.2   misho     184:  * @cfg = Password root
1.1.2.7   misho     185:  * @fields = Meaning continuous field
1.1.2.2   misho     186:  * @csName = Username
1.1.2.8 ! misho     187:  * @arg1 = Password
        !           188:  * @arg2 = UID
        !           189:  * @arg3 = GID
        !           190:  * @arg4 = Login class
        !           191:  * @arg5 = Chage date
        !           192:  * @arg6 = Expire date
        !           193:  * @arg7 = Realm
        !           194:  * @arg8 = Home dir
        !           195:  * @arg9 = Shell
1.1.2.1   misho     196:  * return: 0 nothing changed, -1 error, 1 found and updated item or 2 added new item
                    197:  */
                    198: int
1.1.2.8 ! misho     199: cfg_setPasswd(pwd_root_t * __restrict pwd, u_char fields, const char *csName, ...) 
1.1.2.1   misho     200: {
1.1.2.2   misho     201:        struct tagUser *u;
1.1.2.8 ! misho     202:        register int i;
        !           203:        va_list lst;
1.1.2.1   misho     204: 
1.1.2.2   misho     205:        if (!pwd || !csName)
1.1.2.1   misho     206:                return -1;
                    207: 
1.1.2.2   misho     208:        u = _selectPasswd(pwd, 0, csName);
                    209:        if (!u) {
1.1.2.1   misho     210:                /* adding new element */
1.1.2.2   misho     211:                u = io_malloc(sizeof(struct tagUser));
                    212:                if (!u) {
                    213:                        cfg_SetErr(io_GetErrno(), "%s", io_GetError());
1.1.2.1   misho     214:                        return -1;
                    215:                } else {
1.1.2.2   misho     216:                        memset(u, 0, sizeof(struct tagUser));
1.1.2.7   misho     217:                        if (fields && fields < PWD_MAX_FIELDS)
                    218:                                u->usr_fields = fields;
                    219:                        else
                    220:                                u->usr_fields = PWD_MAX_FIELDS - 1;
1.1.2.1   misho     221: 
1.1.2.2   misho     222:                        PWD_LOCK(pwd);
                    223:                        SLIST_INSERT_HEAD(pwd, u, usr_next);
                    224:                        PWD_UNLOCK(pwd);
1.1.2.1   misho     225:                }
                    226: 
1.1.2.8 ! misho     227:                va_start(lst, csName);
        !           228:                for (i = 0; i < (u->usr_fields + 1); i++)
        !           229:                        switch (i) {
        !           230:                                case 0:
        !           231:                                        AIT_SET_STR(&u->usr_name, va_arg(lst, char*));
        !           232:                                        break;
        !           233:                                case 1:
        !           234:                                        AIT_SET_STR(&u->usr_pass, va_arg(lst, char*));
        !           235:                                        break;
        !           236:                                case 2:
        !           237:                                        AIT_SET_U32(&u->usr_uid, va_arg(lst, u_int));
        !           238:                                        break;
        !           239:                                case 3:
        !           240:                                        AIT_SET_U32(&u->usr_gid, va_arg(lst, u_int));
        !           241:                                        break;
        !           242:                                case 4:
        !           243:                                        AIT_SET_STR(&u->usr_class, va_arg(lst, char*));
        !           244:                                        break;
        !           245:                                case 5:
        !           246:                                        AIT_SET_U32(&u->usr_change, va_arg(lst, u_int));
        !           247:                                        break;
        !           248:                                case 6:
        !           249:                                        AIT_SET_U32(&u->usr_expire, va_arg(lst, u_int));
        !           250:                                        break;
        !           251:                                case 7:
        !           252:                                        AIT_SET_STR(&u->usr_realm, va_arg(lst, char*));
        !           253:                                        break;
        !           254:                                case 8:
        !           255:                                        AIT_SET_STR(&u->usr_home, va_arg(lst, char*));
        !           256:                                        break;
        !           257:                                case 9:
        !           258:                                        AIT_SET_STR(&u->usr_shell, va_arg(lst, char*));
        !           259:                                        break;
        !           260:                        }
        !           261:                va_end(lst);
1.1.2.2   misho     262: 
                    263:                AIT_KEY(&u->usr_name) = crcFletcher16(AIT_GET_LIKE(&u->usr_name, u_short*), 
                    264:                                io_align(AIT_LEN(&u->usr_name) - 1, 2) / 2);
                    265: 
                    266:                PWD_LOCK(pwd);
                    267:                RB_INSERT(tagPWD, pwd, u);
                    268:                PWD_UNLOCK(pwd);
1.1.2.1   misho     269:                return 2;
1.1.2.2   misho     270:        } else {
                    271:                AIT_FREE_VAL(&u->usr_pass);
                    272:                AIT_FREE_VAL(&u->usr_uid);
                    273:                AIT_FREE_VAL(&u->usr_gid);
                    274:                AIT_FREE_VAL(&u->usr_class);
                    275:                AIT_FREE_VAL(&u->usr_change);
                    276:                AIT_FREE_VAL(&u->usr_expire);
                    277:                AIT_FREE_VAL(&u->usr_realm);
                    278:                AIT_FREE_VAL(&u->usr_home);
                    279:                AIT_FREE_VAL(&u->usr_shell);
1.1.2.1   misho     280: 
                    281:                /* Update element */
1.1.2.8 ! misho     282:                va_start(lst, csName);
        !           283:                for (i = 1; i < (u->usr_fields + 1); i++)
        !           284:                        switch (i) {
        !           285:                                case 1:
        !           286:                                        AIT_SET_STR(&u->usr_pass, va_arg(lst, char*));
        !           287:                                        break;
        !           288:                                case 2:
        !           289:                                        AIT_SET_U32(&u->usr_uid, va_arg(lst, u_int));
        !           290:                                        break;
        !           291:                                case 3:
        !           292:                                        AIT_SET_U32(&u->usr_gid, va_arg(lst, u_int));
        !           293:                                        break;
        !           294:                                case 4:
        !           295:                                        AIT_SET_STR(&u->usr_class, va_arg(lst, char*));
        !           296:                                        break;
        !           297:                                case 5:
        !           298:                                        AIT_SET_U32(&u->usr_change, va_arg(lst, u_int));
        !           299:                                        break;
        !           300:                                case 6:
        !           301:                                        AIT_SET_U32(&u->usr_expire, va_arg(lst, u_int));
        !           302:                                        break;
        !           303:                                case 7:
        !           304:                                        AIT_SET_STR(&u->usr_realm, va_arg(lst, char*));
        !           305:                                        break;
        !           306:                                case 8:
        !           307:                                        AIT_SET_STR(&u->usr_home, va_arg(lst, char*));
        !           308:                                        break;
        !           309:                                case 9:
        !           310:                                        AIT_SET_STR(&u->usr_shell, va_arg(lst, char*));
        !           311:                                        break;
        !           312:                        }
        !           313:                va_end(lst);
1.1.2.1   misho     314:                return 1;
                    315:        }
                    316: 
                    317:        /* Nothing happens ... found & values is equal! */
                    318:        return 0;
                    319: }
                    320: 
                    321: /*
1.1.2.2   misho     322:  * cfg_getPasswd() - Get item from passwords and return structure from it
1.1.2.1   misho     323:  *
1.1.2.2   misho     324:  * @pwd = Password root
                    325:  * @criteria = Search criteria [PWD_CRIT_NAME|PWD_CRIT_UID]
                    326:  * @arg1 = Username | UID
                    327:  * return: NULL item not found, !=NULL structure found
1.1.2.1   misho     328:  */
1.1.2.2   misho     329: inline const struct tagUser *
                    330: cfg_getPasswd(pwd_root_t * __restrict pwd, int criteria, ...)
1.1.2.1   misho     331: {
1.1.2.2   misho     332:        struct tagUser *u;
                    333:        va_list lst;
1.1.2.5   misho     334:        char *str;
1.1.2.1   misho     335: 
1.1.2.2   misho     336:        if (!pwd)
1.1.2.1   misho     337:                return NULL;
                    338: 
1.1.2.2   misho     339:        va_start(lst, criteria);
                    340:        switch (criteria) {
                    341:                case PWD_CRIT_NAME:
1.1.2.5   misho     342:                        str = va_arg(lst, char*);
                    343:                        if (!str)
                    344:                                u = NULL;
                    345:                        else
                    346:                                u = _selectPasswd(pwd, 0, str);
1.1.2.2   misho     347:                        break;
                    348:                case PWD_CRIT_UID:
                    349:                        u = _selectPasswd(pwd, va_arg(lst, u_int), NULL);
                    350:                        break;
                    351:                default:
                    352:                        u = NULL;
                    353:                        break;
1.1.2.1   misho     354:        }
1.1.2.2   misho     355:        va_end(lst);
1.1.2.1   misho     356: 
1.1.2.2   misho     357:        return u;
1.1.2.1   misho     358: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>