1 /*
2  *Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches.
3  *
4  *All right reserved
5  *
6  *File Name: expExpressionTable.c
7  *File Description: expExpressionTable MIB operation.
8  *
9  *Current Version:1.0
10  *Author:JianShun Tong
11  *Date:2004.8.20
12  */
13 
14 /*
15  * This file was generated by mib2c and is intended for use as
16  * a mib module for the ucd-snmp snmpd agent.
17  */
18 
19 
20 /*
21  * This should always be included first before anything else
22  */
23 #include <net-snmp/net-snmp-config.h>
24 #include <net-snmp/net-snmp-features.h>
25 #if HAVE_STDLIB_H
26 #include <stdlib.h>
27 #endif
28 #if HAVE_STRING_H
29 #include <string.h>
30 #else
31 #include <strings.h>
32 #endif
33 #ifdef HAVE_LIMITS_H
34 #include <limits.h>
35 #endif
36 
37 
38 /*
39  * minimal include directives
40  */
41 #include <net-snmp/net-snmp-includes.h>
42 #include <net-snmp/agent/net-snmp-agent-includes.h>
43 #include "header_complex.h"
44 #include "expErrorTable.h"
45 #include "expExpressionTable.h"
46 #include "expObjectTable.h"
47 #include "expValueTable.h"
48 
49 netsnmp_feature_require(tdomain_support);
50 #ifndef NETSNMP_NO_WRITE_SUPPORT
51 netsnmp_feature_require(header_complex_find_entry);
52 #endif /* NETSNMP_NO_WRITE_SUPPORT */
53 
54 /*
55  * expExpressionTable_variables_oid:
56  *   this is the top level oid that we want to register under.  This
57  *   is essentially a prefix, with the suffix appearing in the
58  *   variable below.
59  */
60 
61 oid             expExpressionTable_variables_oid[] =
62     { 1, 3, 6, 1, 2, 1, 90, 1, 2, 1 };
63 
64 /*
65  * variable2 expExpressionTable_variables:
66  */
67 
68 struct variable2 expExpressionTable_variables[] = {
69     /*
70      * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix
71      */
72 #define	EXPEXPRESSION  3
73     {EXPEXPRESSION,          ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
74      var_expExpressionTable, 2, {1, 3}},
75 #define	EXPEXPRESSIONVALUETYPE 4
76     {EXPEXPRESSIONVALUETYPE, ASN_INTEGER,   NETSNMP_OLDAPI_RWRITE,
77      var_expExpressionTable, 2, {1, 4}},
78 #define	EXPEXPRESSIONCOMMENT 5
79     {EXPEXPRESSIONCOMMENT,   ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
80      var_expExpressionTable, 2, {1, 5}},
81 #define	EXPEXPRESSIONDELTALNTERVAL 6
82     {EXPEXPRESSIONDELTALNTERVAL, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
83      var_expExpressionTable, 2, {1, 6}},
84 #define	EXPEXPRESSIONPREFIX 7
85     {EXPEXPRESSIONPREFIX,    ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
86      var_expExpressionTable, 2, {1, 7}},
87 #define	EXPEXPRESSIONERRORS 8
88     {EXPEXPRESSIONERRORS,    ASN_UNSIGNED,  NETSNMP_OLDAPI_RONLY,
89      var_expExpressionTable, 2, {1, 8}},
90 #define	EXPEXPRESSIONENTRYSTATUS  9
91     {EXPEXPRESSIONENTRYSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
92      var_expExpressionTable, 2, {1, 9}}
93 };
94 
95 /*
96  * global storage of our data, saved in and configured by header_complex()
97  */
98 
99 struct header_complex_index *expExpressionTableStorage = NULL;
100 
101 oid             mmTimeInstance[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
102 
103 /*
104  * init_expExpressionTable():
105  *   Initialization routine.  This is called when the agent starts up.
106  *   At a minimum, registration of your variables should take place here.
107  */
108 void
init_expExpressionTable(void)109 init_expExpressionTable(void)
110 {
111 
112 
113     /*
114      * register ourselves with the agent to handle our mib tree
115      */
116     REGISTER_MIB("expExpressionTable", expExpressionTable_variables,
117                  variable2, expExpressionTable_variables_oid);
118 
119     /*
120      * register our config handler(s) to deal with registrations
121      */
122     snmpd_register_config_handler("expExpressionTable",
123                                   parse_expExpressionTable, NULL, NULL);
124 
125 
126     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
127                            store_expExpressionTable, NULL);
128 
129 
130     DEBUGMSGTL(("expExpressionTable", "done.\n"));
131 }
132 
133 struct expExpressionTable_data *
create_expExpressionTable_data(void)134 create_expExpressionTable_data(void)
135 {
136     struct expExpressionTable_data *StorageNew;
137     StorageNew = SNMP_MALLOC_STRUCT(expExpressionTable_data);
138     /*
139      * fill in default row values here into StorageNew
140      */
141     /*
142      * fill in values for all tables (even if not
143      * appropriate), since its easier to do here than anywhere
144      * else
145      */
146 
147     StorageNew->expExpression = strdup("");
148     StorageNew->expExpressionValueType = EXPEXPRESSION_COUNTER32;
149     StorageNew->expExpressionComment = strdup("");
150     StorageNew->expExpressionDeltaInterval = 0;
151     StorageNew->expExpressionPrefix = calloc(1, sizeof(oid) * 2);       /* 0.0 */
152     StorageNew->expExpressionPrefixLen = 2;
153     StorageNew->hc_ObjectTableStorage = NULL;
154     StorageNew->hc_ValueTableStorage = NULL;
155     StorageNew->storageType = ST_NONVOLATILE;
156     return StorageNew;
157 }
158 
159 int
expExpressionTable_add(struct expExpressionTable_data * thedata)160 expExpressionTable_add(struct expExpressionTable_data *thedata)
161 {
162     netsnmp_variable_list *vars = NULL;
163 
164 
165     DEBUGMSGTL(("expExpressionTable", "adding data...  "));
166     /*
167      * add the index variables to the varbind list, which is
168      * used by header_complex to index the data
169      */
170     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionOwner, thedata->expExpressionOwnerLen);     /* expExpressionOwner */
171     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->expExpressionName, thedata->expExpressionNameLen);       /* expExpressionName */
172 
173     header_complex_add_data(&expExpressionTableStorage, vars, thedata);
174     DEBUGMSGTL(("expExpressionTable", "registered an entry\n"));
175 
176 
177     DEBUGMSGTL(("expExpressionTable", "done.\n"));
178     return SNMPERR_SUCCESS;
179 }
180 
181 
182 
183 /*
184  * parse_mteTriggerTable():
185  *   parses .conf file entries needed to configure the mib.
186  */
187 void
parse_expExpressionTable(const char * token,char * line)188 parse_expExpressionTable(const char *token, char *line)
189 {
190     size_t          tmpint;
191     oid            *tmpoid = NULL;
192     struct expExpressionTable_data *StorageTmp =
193         SNMP_MALLOC_STRUCT(expExpressionTable_data);
194 
195     DEBUGMSGTL(("expExpressionTable", "parsing config...  "));
196 
197     if (StorageTmp == NULL) {
198         config_perror("malloc failure");
199         return;
200     }
201 
202     line =
203         read_config_read_data(ASN_OCTET_STR, line,
204                               &StorageTmp->expExpressionOwner,
205                               &StorageTmp->expExpressionOwnerLen);
206     if (StorageTmp->expExpressionOwner == NULL) {
207         config_perror("invalid specification for expExpressionOwner");
208         return;
209     }
210 
211     line =
212         read_config_read_data(ASN_OCTET_STR, line,
213                               &StorageTmp->expExpressionName,
214                               &StorageTmp->expExpressionNameLen);
215     if (StorageTmp->expExpressionName == NULL) {
216         config_perror("invalid specification for expExpressionName");
217         return;
218     }
219 
220     line =
221         read_config_read_data(ASN_OCTET_STR, line,
222                               &StorageTmp->expExpression,
223                               &StorageTmp->expExpressionLen);
224 
225     line =
226         read_config_read_data(ASN_INTEGER, line,
227                               &StorageTmp->expExpressionValueType,
228                               &tmpint);
229 
230     line =
231         read_config_read_data(ASN_OCTET_STR, line,
232                               &StorageTmp->expExpressionComment,
233                               &StorageTmp->expExpressionCommentLen);
234 
235     line =
236         read_config_read_data(ASN_INTEGER, line,
237                               &StorageTmp->expExpressionDeltaInterval,
238                               &tmpint);
239 
240     line =
241         read_config_read_data(ASN_OBJECT_ID, line,
242                               &StorageTmp->expExpressionPrefix,
243                               &StorageTmp->expExpressionPrefixLen);
244 
245     line =
246         read_config_read_data(ASN_UNSIGNED, line,
247                               &StorageTmp->expExpressionErrors, &tmpint);
248 
249     line =
250         read_config_read_data(ASN_INTEGER, line,
251                               &StorageTmp->expExpressionEntryStatus,
252                               &tmpint);
253 
254     line =
255         read_config_read_data(ASN_INTEGER, line,
256                               &StorageTmp->have_copied_auth_info, &tmpint);
257     if (StorageTmp->have_copied_auth_info) {
258         line =
259             read_config_read_data(ASN_INTEGER, line,
260                                   &StorageTmp->pdu_version, &tmpint);
261         line =
262             read_config_read_data(ASN_INTEGER, line,
263                                   &StorageTmp->pdu_securityModel, &tmpint);
264         line =
265             read_config_read_data(ASN_INTEGER, line,
266                                   &StorageTmp->pdu_securityLevel, &tmpint);
267         line =
268             read_config_read_data(ASN_OBJECT_ID, line, &tmpoid, &tmpint);
269         if (!netsnmp_tdomain_support
270             (tmpoid, tmpint, &StorageTmp->pdu_tDomain,
271              &StorageTmp->pdu_tDomainLen)) {
272             config_perror
273                 ("unsupported transport domain for mteTriggerEntry");
274             return;
275         }
276         if (tmpoid != NULL) {
277             free(tmpoid);
278         }
279 
280         /*
281          * can be NULL?  Yes.
282          */
283         line = read_config_read_data(ASN_OCTET_STR, line,
284                                      &(StorageTmp->pdu_transport),
285                                      &StorageTmp->pdu_transportLen);
286 
287         line =
288             read_config_read_data(ASN_OCTET_STR, line,
289                                   &StorageTmp->pdu_community,
290                                   &StorageTmp->pdu_community_len);
291         if (StorageTmp->pdu_community == NULL) {
292             config_perror("invalid specification for pdu_community");
293             return;
294         }
295         line =
296             read_config_read_data(ASN_OCTET_STR, line,
297                                   &StorageTmp->pdu_securityName,
298                                   &StorageTmp->pdu_securityNameLen);
299         if (StorageTmp->pdu_securityName == NULL) {
300             config_perror("invalid specification for pdu_securityName");
301             return;
302         }
303     }
304     StorageTmp->storageType = ST_NONVOLATILE;
305     expExpressionTable_add(StorageTmp);
306 
307 
308     DEBUGMSGTL(("expExpressionTable", "done.\n"));
309 }
310 
311 
312 /*
313  * store_expExpressionTable():
314  *   stores .conf file entries needed to configure the mib.
315  */
316 int
store_expExpressionTable(int majorID,int minorID,void * serverarg,void * clientarg)317 store_expExpressionTable(int majorID, int minorID, void *serverarg,
318                          void *clientarg)
319 {
320     char            line[SNMP_MAXBUF];
321     char           *cptr;
322     size_t          tmpint;
323     struct expExpressionTable_data *StorageTmp;
324     struct header_complex_index *hcindex;
325 
326     DEBUGMSGTL(("expExpressionTable", "storing data...  "));
327 
328     for (hcindex = expExpressionTableStorage; hcindex != NULL;
329          hcindex = hcindex->next) {
330         StorageTmp = (struct expExpressionTable_data *) hcindex->data;
331 
332 
333         if (StorageTmp->storageType == ST_NONVOLATILE) {
334 
335             memset(line, 0, sizeof(line));
336             strcat(line, "expExpressionTable ");
337             cptr = line + strlen(line);
338             /*
339              * expExpressionTable
340              */
341 
342 
343             cptr =
344                 read_config_store_data(ASN_OCTET_STR, cptr,
345                                        &StorageTmp->expExpressionOwner,
346                                        &StorageTmp->expExpressionOwnerLen);
347             cptr =
348                 read_config_store_data(ASN_OCTET_STR, cptr,
349                                        &StorageTmp->expExpressionName,
350                                        &StorageTmp->expExpressionNameLen);
351             cptr =
352                 read_config_store_data(ASN_OCTET_STR, cptr,
353                                        &StorageTmp->expExpression,
354                                        &StorageTmp->expExpressionLen);
355             cptr =
356                 read_config_store_data(ASN_INTEGER, cptr,
357                                        &StorageTmp->expExpressionValueType,
358                                        &tmpint);
359             cptr =
360                 read_config_store_data(ASN_OCTET_STR, cptr,
361                                        &StorageTmp->expExpressionComment,
362                                        &StorageTmp->
363                                        expExpressionCommentLen);
364             cptr =
365                 read_config_store_data(ASN_INTEGER, cptr,
366                                        &StorageTmp->
367                                        expExpressionDeltaInterval,
368                                        &tmpint);
369             cptr =
370                 read_config_store_data(ASN_OBJECT_ID, cptr,
371                                        &StorageTmp->expExpressionPrefix,
372                                        &StorageTmp->
373                                        expExpressionPrefixLen);
374             cptr =
375                 read_config_store_data(ASN_UNSIGNED, cptr,
376                                        &StorageTmp->expExpressionErrors,
377                                        &tmpint);
378             cptr =
379                 read_config_store_data(ASN_INTEGER, cptr,
380                                        &StorageTmp->
381                                        expExpressionEntryStatus, &tmpint);
382             cptr =
383                 read_config_store_data(ASN_INTEGER, cptr,
384                                        &StorageTmp->have_copied_auth_info,
385                                        &tmpint);
386             if (StorageTmp->have_copied_auth_info) {
387                 cptr =
388                     read_config_store_data(ASN_INTEGER, cptr,
389                                            &StorageTmp->pdu_version,
390                                            &tmpint);
391                 cptr =
392                     read_config_store_data(ASN_INTEGER, cptr,
393                                            &StorageTmp->pdu_securityModel,
394                                            &tmpint);
395                 cptr =
396                     read_config_store_data(ASN_INTEGER, cptr,
397                                            &StorageTmp->pdu_securityLevel,
398                                            &tmpint);
399                 cptr =
400                     read_config_store_data(ASN_OBJECT_ID, cptr,
401                                            (void *) (&StorageTmp->
402                                                      pdu_tDomain),
403                                            &StorageTmp->pdu_tDomainLen);
404                 cptr =
405                     read_config_store_data(ASN_OCTET_STR, cptr,
406                                            &StorageTmp->pdu_transport,
407                                            &StorageTmp->pdu_transportLen);
408                 cptr =
409                     read_config_store_data(ASN_OCTET_STR, cptr,
410                                            &StorageTmp->pdu_community,
411                                            &StorageTmp->pdu_community_len);
412                 cptr =
413                     read_config_store_data(ASN_OCTET_STR, cptr,
414                                            &StorageTmp->pdu_securityName,
415                                            &StorageTmp->
416                                            pdu_securityNameLen);
417             }
418 
419 
420             snmpd_store_config(line);
421         }
422     }
423     DEBUGMSGTL(("expExpressionTable", "storage done.\n"));
424     return SNMPERR_SUCCESS;
425 }
426 
427 
428 
429 
430 /*
431  * var_expExpressionTable():
432  *   Handle this table separately from the scalar value case.
433  *   The workings of this are basically the same as for var_expExpressionTable above.
434  */
435 unsigned char  *
var_expExpressionTable(struct variable * vp,oid * name,size_t * length,int exact,size_t * var_len,WriteMethod ** write_method)436 var_expExpressionTable(struct variable *vp,
437                        oid * name,
438                        size_t *length,
439                        int exact,
440                        size_t *var_len, WriteMethod ** write_method)
441 {
442     struct expExpressionTable_data *StorageTmp = NULL;
443 
444     DEBUGMSGTL(("expExpressionTable",
445                 "var_expExpressionTable: Entering...  \n"));
446 
447     /*
448      * this assumes you have registered all your data properly
449      */
450     if ((StorageTmp =
451          header_complex(expExpressionTableStorage, vp, name, length, exact,
452                         var_len, write_method)) == NULL) {
453         if (vp->magic == EXPEXPRESSIONENTRYSTATUS)
454             *write_method = write_expExpressionEntryStatus;
455         return NULL;
456     }
457 
458 
459     switch (vp->magic) {
460 
461 
462     case EXPEXPRESSION:
463         *write_method = write_expExpression;
464         *var_len = StorageTmp->expExpressionLen;
465         return (u_char *) StorageTmp->expExpression;
466 
467     case EXPEXPRESSIONVALUETYPE:
468         *write_method = write_expExpressionValueType;
469         *var_len = sizeof(StorageTmp->expExpressionValueType);
470         return (u_char *) & StorageTmp->expExpressionValueType;
471 
472     case EXPEXPRESSIONCOMMENT:
473         *write_method = write_expExpressionComment;
474         *var_len = StorageTmp->expExpressionCommentLen;
475         return (u_char *) StorageTmp->expExpressionComment;
476 
477     case EXPEXPRESSIONDELTALNTERVAL:
478         *write_method = write_expExpressionDeltaInterval;
479         *var_len = sizeof(StorageTmp->expExpressionDeltaInterval);
480         return (u_char *) & StorageTmp->expExpressionDeltaInterval;
481 
482     case EXPEXPRESSIONPREFIX:
483         *var_len = StorageTmp->expExpressionPrefixLen * sizeof(oid);
484         return (u_char *) StorageTmp->expExpressionPrefix;
485 
486     case EXPEXPRESSIONERRORS:
487         *var_len = sizeof(StorageTmp->expExpressionErrors);
488         return (u_char *) & StorageTmp->expExpressionErrors;
489 
490     case EXPEXPRESSIONENTRYSTATUS:
491         *write_method = write_expExpressionEntryStatus;
492         *var_len = sizeof(StorageTmp->expExpressionEntryStatus);
493         return (u_char *) & StorageTmp->expExpressionEntryStatus;
494 
495     default:
496         ERROR_MSG("");
497 
498     }
499     return NULL;
500 }
501 
502 
503 
504 int
write_expExpression(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)505 write_expExpression(int action,
506                     u_char * var_val,
507                     u_char var_val_type,
508                     size_t var_val_len,
509                     u_char * statP, oid * name, size_t name_len)
510 {
511     static char    *tmpvar;
512     struct expExpressionTable_data *StorageTmp = NULL;
513     static size_t   tmplen;
514     size_t          newlen =
515         name_len -
516         (sizeof(expExpressionTable_variables_oid) / sizeof(oid) + 3 - 1);
517 
518 
519     DEBUGMSGTL(("expExpressionTable",
520                 "write_expExpression entering action=%d...  \n", action));
521     if ((StorageTmp =
522          header_complex(expExpressionTableStorage, NULL,
523                         &name[sizeof(expExpressionTable_variables_oid) /
524                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
525                         NULL)) == NULL)
526         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
527 
528 
529     switch (action) {
530     case RESERVE1:
531         if (var_val_type != ASN_OCTET_STR) {
532             snmp_log(LOG_ERR,
533                      "write to expExpression not ASN_OCTET_STR\n");
534             return SNMP_ERR_WRONGTYPE;
535         }
536         if (StorageTmp->storageType != ST_NONVOLATILE)
537             return SNMP_ERR_NOTWRITABLE;
538 
539         break;
540 
541 
542     case RESERVE2:
543         /*
544          * memory reseveration, final preparation...
545          */
546         break;
547 
548 
549     case FREE:
550         /*
551          * Release any resources that have been allocated
552          */
553         break;
554 
555 
556     case ACTION:
557         /*
558          * The variable has been stored in string for
559          * you to use, and you have just been asked to do something with
560          * it.  Note that anything done here must be reversable in the UNDO case
561          */
562         tmpvar = StorageTmp->expExpression;
563         tmplen = StorageTmp->expExpressionLen;
564         StorageTmp->expExpression = malloc(var_val_len + 1);
565         if (StorageTmp->expExpression)
566             snprintf(StorageTmp->expExpression, var_val_len + 1, "%.*s",
567                      (int)var_val_len, var_val);
568         StorageTmp->expExpressionLen = var_val_len;
569         break;
570 
571 
572     case UNDO:
573         /*
574          * Back out any changes made in the ACTION case
575          */
576         SNMP_FREE(StorageTmp->expExpression);
577         StorageTmp->expExpression = tmpvar;
578         StorageTmp->expExpressionLen = tmplen;
579         break;
580 
581 
582     case COMMIT:
583         /*
584          * Things are working well, so it's now safe to make the change
585          * permanently.  Make sure that anything done here can't fail!
586          */
587         SNMP_FREE(tmpvar);
588         snmp_store_needed(NULL);
589         break;
590     }
591     return SNMP_ERR_NOERROR;
592 
593 }
594 
595 
596 
597 int
write_expExpressionValueType(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)598 write_expExpressionValueType(int action,
599                              u_char * var_val,
600                              u_char var_val_type,
601                              size_t var_val_len,
602                              u_char * statP, oid * name, size_t name_len)
603 {
604     static int      tmpvar;
605     struct expExpressionTable_data *StorageTmp = NULL;
606     size_t          newlen =
607         name_len -
608         (sizeof(expExpressionTable_variables_oid) / sizeof(oid) + 3 - 1);
609 
610 
611     DEBUGMSGTL(("expExpressionTable",
612                 "write_expExpressionValueType entering action=%d...  \n",
613                 action));
614     if ((StorageTmp =
615          header_complex(expExpressionTableStorage, NULL,
616                         &name[sizeof(expExpressionTable_variables_oid) /
617                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
618                         NULL)) == NULL)
619         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
620 
621 
622     switch (action) {
623     case RESERVE1:
624         if (var_val_type != ASN_INTEGER) {
625             snmp_log(LOG_ERR,
626                      "write to expExpressionValueType not ASN_INTEGER\n");
627             return SNMP_ERR_WRONGTYPE;
628         }
629         if (StorageTmp->storageType != ST_NONVOLATILE)
630             return SNMP_ERR_NOTWRITABLE;
631 
632         break;
633 
634 
635     case RESERVE2:
636         /*
637          * memory reseveration, final preparation...
638          */
639         break;
640 
641 
642     case FREE:
643         /*
644          * Release any resources that have been allocated
645          */
646         break;
647 
648 
649     case ACTION:
650         /*
651          * The variable has been stored in string for
652          * you to use, and you have just been asked to do something with
653          * it.  Note that anything done here must be reversable in the UNDO case
654          */
655         tmpvar = StorageTmp->expExpressionValueType;
656         StorageTmp->expExpressionValueType = *((long *) var_val);
657         break;
658 
659 
660     case UNDO:
661         /*
662          * Back out any changes made in the ACTION case
663          */
664         StorageTmp->expExpressionValueType = tmpvar;
665         break;
666 
667 
668     case COMMIT:
669         /*
670          * Things are working well, so it's now safe to make the change
671          * permanently.  Make sure that anything done here can't fail!
672          */
673         snmp_store_needed(NULL);
674         break;
675     }
676     return SNMP_ERR_NOERROR;
677 
678 }
679 
680 
681 int
write_expExpressionComment(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)682 write_expExpressionComment(int action,
683                            u_char * var_val,
684                            u_char var_val_type,
685                            size_t var_val_len,
686                            u_char * statP, oid * name, size_t name_len)
687 {
688     static char    *tmpvar;
689     struct expExpressionTable_data *StorageTmp = NULL;
690     static size_t   tmplen;
691     size_t          newlen =
692         name_len -
693         (sizeof(expExpressionTable_variables_oid) / sizeof(oid) + 3 - 1);
694 
695 
696     DEBUGMSGTL(("expExpressionTable",
697                 "write_expExpression entering action=%d...  \n", action));
698     if ((StorageTmp =
699          header_complex(expExpressionTableStorage, NULL,
700                         &name[sizeof(expExpressionTable_variables_oid) /
701                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
702                         NULL)) == NULL)
703         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
704 
705 
706     switch (action) {
707     case RESERVE1:
708         if (var_val_type != ASN_OCTET_STR) {
709             snmp_log(LOG_ERR,
710                      "write to expExpressionComment not ASN_OCTET_STR\n");
711             return SNMP_ERR_WRONGTYPE;
712         }
713         if (StorageTmp->storageType != ST_NONVOLATILE)
714             return SNMP_ERR_NOTWRITABLE;
715 
716         break;
717 
718 
719     case RESERVE2:
720         /*
721          * memory reseveration, final preparation...
722          */
723         break;
724 
725 
726     case FREE:
727         /*
728          * Release any resources that have been allocated
729          */
730         break;
731 
732 
733     case ACTION:
734         /*
735          * The variable has been stored in string for
736          * you to use, and you have just been asked to do something with
737          * it.  Note that anything done here must be reversable in the UNDO case
738          */
739         tmpvar = StorageTmp->expExpressionComment;
740         tmplen = StorageTmp->expExpressionCommentLen;
741         StorageTmp->expExpressionComment = netsnmp_memdup(var_val, var_val_len);
742         StorageTmp->expExpressionCommentLen = var_val_len;
743         break;
744 
745 
746     case UNDO:
747         /*
748          * Back out any changes made in the ACTION case
749          */
750         SNMP_FREE(StorageTmp->expExpressionComment);
751         StorageTmp->expExpressionComment = tmpvar;
752         StorageTmp->expExpressionCommentLen = tmplen;
753         break;
754 
755 
756     case COMMIT:
757         /*
758          * Things are working well, so it's now safe to make the change
759          * permanently.  Make sure that anything done here can't fail!
760          */
761         SNMP_FREE(tmpvar);
762         snmp_store_needed(NULL);
763         break;
764     }
765     return SNMP_ERR_NOERROR;
766 
767 }
768 
769 
770 int
write_expExpressionDeltaInterval(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)771 write_expExpressionDeltaInterval(int action,
772                                  u_char * var_val,
773                                  u_char var_val_type,
774                                  size_t var_val_len,
775                                  u_char * statP, oid * name,
776                                  size_t name_len)
777 {
778     static int      tmpvar;
779     struct expExpressionTable_data *StorageTmp = NULL;
780     size_t          newlen =
781         name_len -
782         (sizeof(expExpressionTable_variables_oid) / sizeof(oid) + 3 - 1);
783 
784 
785     DEBUGMSGTL(("expExpressionTable",
786                 "write_expExpressionValueType entering action=%d...  \n",
787                 action));
788     if ((StorageTmp =
789          header_complex(expExpressionTableStorage, NULL,
790                         &name[sizeof(expExpressionTable_variables_oid) /
791                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
792                         NULL)) == NULL)
793         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
794 
795 
796     switch (action) {
797     case RESERVE1:
798         if (var_val_type != ASN_INTEGER) {
799             snmp_log(LOG_ERR,
800                      "write to expExpressionDeltalnterval not ASN_INTEGER\n");
801             return SNMP_ERR_WRONGTYPE;
802         }
803         if (StorageTmp->storageType != ST_NONVOLATILE)
804             return SNMP_ERR_NOTWRITABLE;
805 
806         break;
807 
808 
809     case RESERVE2:
810         /*
811          * memory reseveration, final preparation...
812          */
813         break;
814 
815 
816     case FREE:
817         /*
818          * Release any resources that have been allocated
819          */
820         break;
821 
822 
823     case ACTION:
824         /*
825          * The variable has been stored in string for
826          * you to use, and you have just been asked to do something with
827          * it.  Note that anything done here must be reversable in the UNDO case
828          */
829         tmpvar = StorageTmp->expExpressionDeltaInterval;
830         StorageTmp->expExpressionDeltaInterval = *((long *) var_val);
831         break;
832 
833 
834     case UNDO:
835         /*
836          * Back out any changes made in the ACTION case
837          */
838         StorageTmp->expExpressionDeltaInterval = tmpvar;
839         break;
840 
841 
842     case COMMIT:
843         /*
844          * Things are working well, so it's now safe to make the change
845          * permanently.  Make sure that anything done here can't fail!
846          */
847         snmp_store_needed(NULL);
848         break;
849     }
850     return SNMP_ERR_NOERROR;
851 
852 }
853 
854 
855 int
write_expExpressionEntryStatus(int action,u_char * var_val,u_char var_val_type,size_t var_val_len,u_char * statP,oid * name,size_t name_len)856 write_expExpressionEntryStatus(int action,
857                                u_char * var_val,
858                                u_char var_val_type,
859                                size_t var_val_len,
860                                u_char * statP, oid * name, size_t name_len)
861 {
862     struct expExpressionTable_data *StorageTmp = NULL;
863     static struct expExpressionTable_data *StorageNew, *StorageDel;
864     size_t          newlen =
865         name_len -
866         (sizeof(expExpressionTable_variables_oid) / sizeof(oid) + 3 - 1);
867     static int      old_value;
868     int             set_value;
869     static netsnmp_variable_list *vars, *vp;
870     struct header_complex_index *hciptr;
871 
872     StorageTmp =
873         header_complex(expExpressionTableStorage, NULL,
874                        &name[sizeof(expExpressionTable_variables_oid) /
875                              sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);
876 
877 
878 
879 
880     if (var_val_type != ASN_INTEGER || var_val == NULL) {
881         snmp_log(LOG_ERR,
882                  "write to expExpressionEntryStatus not ASN_INTEGER\n");
883         return SNMP_ERR_WRONGTYPE;
884     }
885     set_value = *((long *) var_val);
886 
887 
888     /*
889      * check legal range, and notReady is reserved for us, not a user
890      */
891     if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY)
892         return SNMP_ERR_INCONSISTENTVALUE;
893 
894 
895     switch (action) {
896     case RESERVE1:
897         /*
898          * stage one: test validity
899          */
900         if (StorageTmp == NULL) {
901             /*
902              * create the row now?
903              */
904 
905 
906             /*
907              * ditch illegal values now
908              */
909             if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE)
910                 return SNMP_ERR_INCONSISTENTVALUE;
911 
912 
913             /*
914              * destroying a non-existent row is actually legal
915              */
916             if (set_value == RS_DESTROY) {
917                 return SNMP_ERR_NOERROR;
918             }
919 
920 
921             /*
922              * illegal creation values
923              */
924             if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
925                 return SNMP_ERR_INCONSISTENTVALUE;
926             }
927         } else {
928             /*
929              * row exists.  Check for a valid state change
930              */
931             if (set_value == RS_CREATEANDGO
932                 || set_value == RS_CREATEANDWAIT) {
933                 /*
934                  * can't create a row that exists
935                  */
936                 return SNMP_ERR_INCONSISTENTVALUE;
937             }
938 
939             if (StorageTmp->expExpressionEntryStatus == RS_ACTIVE &&
940                 set_value != RS_DESTROY) {
941                 /*
942                  * "Once made active an entry may not be modified except to
943                  * delete it."  XXX: doesn't this in fact apply to ALL
944                  * columns of the table and not just this one?
945                  */
946                 return SNMP_ERR_INCONSISTENTVALUE;
947             }
948             if (StorageTmp->storageType != ST_NONVOLATILE)
949                 return SNMP_ERR_NOTWRITABLE;
950         }
951         break;
952 
953 
954 
955 
956     case RESERVE2:
957         /*
958          * memory reseveration, final preparation...
959          */
960         if (StorageTmp == NULL) {
961             /*
962              * creation
963              */
964             vars = NULL;
965 
966 
967             snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* expExpressionOwner */
968             snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* expExpressionName */
969 
970 
971 
972             if (header_complex_parse_oid
973                 (&
974                  (name
975                   [sizeof(expExpressionTable_variables_oid) / sizeof(oid) +
976                    2]), newlen, vars) != SNMPERR_SUCCESS) {
977                 /*
978                  * XXX: free, zero vars
979                  */
980                 return SNMP_ERR_INCONSISTENTNAME;
981             }
982             vp = vars;
983 
984 
985             StorageNew = create_expExpressionTable_data();
986 
987             StorageNew->expExpressionOwner = malloc(vp->val_len + 1);
988             memcpy(StorageNew->expExpressionOwner, vp->val.string,
989                    vp->val_len);
990             StorageNew->expExpressionOwner[vp->val_len] = '\0';
991             StorageNew->expExpressionOwnerLen = vp->val_len;
992 
993             vp = vp->next_variable;
994             StorageNew->expExpressionName = malloc(vp->val_len + 1);
995             memcpy(StorageNew->expExpressionName, vp->val.string,
996                    vp->val_len);
997             StorageNew->expExpressionName[vp->val_len] = '\0';
998             StorageNew->expExpressionNameLen = vp->val_len;
999 
1000             vp = vp->next_variable;
1001 
1002             StorageNew->expExpressionEntryStatus = set_value;
1003 
1004         }
1005 
1006 
1007         break;
1008 
1009 
1010 
1011 
1012     case FREE:
1013         /*
1014          * XXX: free, zero vars
1015          */
1016         /*
1017          * Release any resources that have been allocated
1018          */
1019         break;
1020 
1021 
1022 
1023 
1024     case ACTION:
1025         /*
1026          * The variable has been stored in set_value for you to
1027          * use, and you have just been asked to do something with
1028          * it.  Note that anything done here must be reversable in
1029          * the UNDO case
1030          */
1031 
1032 
1033         if (StorageTmp == NULL && set_value != RS_DESTROY) {
1034             /*
1035              * row creation, so add it
1036              */
1037             if (StorageNew != NULL)
1038                 expExpressionTable_add(StorageNew);
1039             /*
1040              * XXX: ack, and if it is NULL?
1041              */
1042         } else if (StorageTmp && set_value != RS_DESTROY) {
1043             /*
1044              * set the flag?
1045              */
1046             old_value = StorageTmp->expExpressionEntryStatus;
1047             StorageTmp->expExpressionEntryStatus = *((long *) var_val);
1048         } else {
1049             /*
1050              * destroy...  extract it for now
1051              */
1052             hciptr =
1053                 header_complex_find_entry(expExpressionTableStorage,
1054                                           StorageTmp);
1055             StorageDel =
1056                 header_complex_extract_entry(&expExpressionTableStorage,
1057                                              hciptr);
1058         }
1059         break;
1060 
1061 
1062 
1063 
1064     case UNDO:
1065         /*
1066          * Back out any changes made in the ACTION case
1067          */
1068         if (StorageTmp == NULL) {
1069             /*
1070              * row creation, so remove it again
1071              */
1072             hciptr =
1073                 header_complex_find_entry(expExpressionTableStorage,
1074                                           StorageTmp);
1075             StorageDel =
1076                 header_complex_extract_entry(&expExpressionTableStorage,
1077                                              hciptr);
1078             /*
1079              * XXX: free it
1080              */
1081         } else if (StorageDel != NULL) {
1082             /*
1083              * row deletion, so add it again
1084              */
1085             expExpressionTable_add(StorageDel);
1086         } else {
1087             StorageTmp->expExpressionEntryStatus = old_value;
1088         }
1089         break;
1090 
1091 
1092 
1093 
1094     case COMMIT:
1095         /*
1096          * Things are working well, so it's now safe to make the change
1097          * permanently.  Make sure that anything done here can't fail!
1098          */
1099         if (StorageDel != NULL) {
1100             StorageDel = 0;
1101             /*
1102              * XXX: free it, its dead
1103              */
1104         } else {
1105             if (StorageTmp
1106                 && StorageTmp->expExpressionEntryStatus ==
1107                 RS_CREATEANDGO) {
1108                 StorageTmp->expExpressionEntryStatus = RS_ACTIVE;
1109             } else if (StorageTmp &&
1110                        StorageTmp->expExpressionEntryStatus ==
1111                        RS_CREATEANDWAIT) {
1112                 StorageTmp->expExpressionEntryStatus = RS_NOTINSERVICE;
1113             }
1114         }
1115         if (StorageTmp &&
1116             StorageTmp->expExpressionEntryStatus == RS_ACTIVE &&
1117             !StorageTmp->have_copied_auth_info) {
1118 
1119             netsnmp_agent_session *asp =
1120                 netsnmp_get_current_agent_session();
1121             netsnmp_pdu    *pdu = NULL;
1122 
1123             if (!asp) {
1124                 snmp_log(LOG_ERR,
1125                          "snmpTriggerTable: can't get master session for authentication params\n");
1126             } else {
1127                 pdu = asp->orig_pdu;
1128                 if (!pdu) {
1129                     snmp_log(LOG_ERR,
1130                              "snmpTriggerTable: can't get master pdu for authentication params\n");
1131                 }
1132             }
1133 
1134             if (pdu) {
1135                 DEBUGMSGTL(("expExpressionTest",
1136                             "copying PDU auth info\n"));
1137                 StorageTmp->pdu_version = pdu->version;
1138                 StorageTmp->pdu_securityModel = pdu->securityModel;
1139                 StorageTmp->pdu_securityLevel = pdu->securityLevel;
1140                 StorageTmp->pdu_tDomain = pdu->tDomain;
1141                 StorageTmp->pdu_tDomainLen = pdu->tDomainLen;
1142                 if (pdu->transport_data != NULL) {
1143                     StorageTmp->pdu_transport =
1144                         malloc(pdu->transport_data_length);
1145                     memcpy(StorageTmp->pdu_transport, pdu->transport_data,
1146                            pdu->transport_data_length);
1147                 }
1148                 StorageTmp->pdu_transportLen = pdu->transport_data_length;
1149                 if (pdu->community) {
1150                     StorageTmp->pdu_community =
1151                         calloc(1, pdu->community_len + 1);
1152                     memcpy(StorageTmp->pdu_community, pdu->community,
1153                            pdu->community_len);
1154                     StorageTmp->pdu_community_len = pdu->community_len;
1155                 } else {
1156                     StorageTmp->pdu_community = NULL;
1157                     StorageTmp->pdu_community_len = 0;
1158                 }
1159                 if (pdu->securityName) {
1160                     StorageTmp->pdu_securityName =
1161                         calloc(1, pdu->securityNameLen + 1);
1162                     memcpy(StorageTmp->pdu_securityName, pdu->securityName,
1163                            pdu->securityNameLen);
1164                     StorageTmp->pdu_securityNameLen = pdu->securityNameLen;
1165                 } else {
1166                     StorageTmp->pdu_securityName = NULL;
1167                     StorageTmp->pdu_securityNameLen = 0;
1168                 }
1169                 StorageTmp->have_copied_auth_info = 1;
1170             }
1171         }
1172         snmp_store_needed(NULL);
1173         break;
1174     }
1175     return SNMP_ERR_NOERROR;
1176 }
1177