-/* Parse an LDIF control line of the form
- control: oid [true/false] [: value] or
- control: oid [true/false] [:: base64-value] or
- control: oid [true/false] [:< url]
- The control is added to the list of controls in *ppctrls.
-*/
-static int
-parse_ldif_control( char *line,
- LDAPControl ***ppctrls )
-{
- char *oid = NULL;
- int criticality = 0; /* Default is false if not present */
- char *type=NULL;
- char *val = NULL;
- ber_len_t value_len = 0;
- int i, rc=0;
- char *s, *oidStart, *pcolon;
- LDAPControl *newctrl = NULL;
- LDAPControl **pctrls = NULL;
-
- if (ppctrls) {
- pctrls = *ppctrls;
- }
- s = line + strlen(T_CONTROL_STR); /* Skip over "control" */
- pcolon = s; /* Save this position for later */
- if (*s++ != ':') /* Make sure colon follows */
- return ( LDAP_PARAM_ERROR );
- while (*s && isspace(*s)) s++; /* Skip white space before OID */
-
- /* OID should come next. Validate and extract it. */
- if (*s == 0)
- return ( LDAP_PARAM_ERROR );
- oidStart = s;
- while (isdigit(*s) || *s == '.') s++; /* OID should be digits or . */
- if (s == oidStart)
- return ( LDAP_PARAM_ERROR ); /* OID was not present */
- if (*s) { /* End of OID should be space or NULL */
- if (!isspace(*s))
- return ( LDAP_PARAM_ERROR ); /* else OID contained invalid chars */
- *s++ = 0; /* Replace space with null to terminate */
- }
-
-
- oid = ber_strdup(oidStart);
- if (oid == NULL)
- return ( LDAP_NO_MEMORY );
-
- /* Optional Criticality field is next. */
- while (*s && isspace(*s)) s++; /* Skip white space before criticality */
- if (strncasecmp(s, "true", 4) == 0) {
- criticality = 1;
- s += 4;
- }
- else if (strncasecmp(s, "false", 5) == 0) {
- criticality = 0;
- s += 5;
- }
-
- /* Optional value field is next */
- while (*s && isspace(*s)) s++; /* Skip white space before value */
- if (*s) {
- if (*s != ':') { /* If value is present, must start with : */
- rc = LDAP_PARAM_ERROR;
- goto cleanup;
- }
-
- /* Shift value down over OID and criticality so it's in the form
- control: value
- control:: base64-value
- control:< url
- Then we can use ldif_parse_line to extract and decode the value
- */
- while ( (*pcolon++ = *s++) != 0) /* Shift value */
- ;
- rc = ldif_parse_line(line, &type, &val, &value_len);
- if (type) ber_memfree(type); /* Don't need this field*/
- if (rc < 0) {
- rc = LDAP_PARAM_ERROR;
- goto cleanup;
- }
- }
-
- /* Create a new LDAPControl structure. */
- newctrl = (LDAPControl *)ber_memalloc(sizeof(LDAPControl));
- if ( newctrl == NULL ) {
- rc = LDAP_NO_MEMORY;
- goto cleanup;
- }
- newctrl->ldctl_oid = oid;
- oid = NULL;
- newctrl->ldctl_iscritical = criticality;
- newctrl->ldctl_value.bv_len = value_len;
- newctrl->ldctl_value.bv_val = val;
- val = NULL;
-
- /* Add the new control to the passed-in list of controls. */
- i = 0;
- if (pctrls) {
- while ( pctrls[i] ) /* Count the # of controls passed in */
- i++;
- }
- /* Allocate 1 more slot for the new control and 1 for the NULL. */
- pctrls = (LDAPControl **)ber_memrealloc(pctrls, (i+2)*(sizeof(LDAPControl *)));
- if (pctrls == NULL) {
- rc = LDAP_NO_MEMORY;
- goto cleanup;
- }
- pctrls[i] = newctrl;
- newctrl = NULL;
- pctrls[i+1] = NULL;
- *ppctrls = pctrls;
-
-cleanup:
- if (newctrl) {
- if (newctrl->ldctl_oid)
- ber_memfree(newctrl->ldctl_oid);
- if (newctrl->ldctl_value.bv_val)
- ber_memfree(newctrl->ldctl_value.bv_val);
- ber_memfree(newctrl);
- }
- if (val)
- ber_memfree(val);
- if (oid)
- ber_memfree(oid);
-
- return( rc );