/* * Check if username in specified header field is in a table */ int is_user_in(struct sip_msg* _msg, char* _hf, char* _grp) { db_key_t keys[3]; db_val_t vals[3]; db_key_t col[1]; db_res_t* res; str uri; long hf_type; struct sip_uri puri; struct hdr_field* h; struct auth_body* c = 0; /* Makes gcc happy */ group_check_p gcp=NULL; xl_value_t value; keys[0] = user_column.s; keys[1] = group_column.s; keys[2] = domain_column.s; col[0] = group_column.s; gcp = (group_check_p)_hf; hf_type = (long)gcp->id; uri.s = 0; uri.len = 0; switch(hf_type) { case 1: /* Request-URI */ if (get_request_uri(_msg, &uri) < 0) { LOG(L_ERR, "is_user_in(): Error while obtaining username from Request-URI\n"); return -1; } break; case 2: /* To */ if (get_to_uri(_msg, &uri) < 0) { LOG(L_ERR, "is_user_in(): Error while extracting To username\n"); return -2; } break; case 3: /* From */ if (get_from_uri(_msg, &uri) < 0) { LOG(L_ERR, "is_user_in(): Error while extracting From username\n"); return -3; } break; case 4: /* Credentials */ get_authorized_cred(_msg->authorization, &h); if (!h) { get_authorized_cred(_msg->proxy_auth, &h); if (!h) { LOG(L_ERR, "is_user_in(): No authorized credentials found (error in scripts)\n"); return -1; } } c = (auth_body_t*)(h->parsed); break; case 5: /* AVP spec */ if(xl_get_spec_value(_msg, &gcp->sp, &value)!=0 || value.flags&XL_VAL_NULL || value.rs.len<=0) { LOG(L_ERR, "is_user_in(): no AVP found (error in scripts)\n"); return -1; } uri.s = value.rs.s; uri.len = value.rs.len; break; } if (hf_type != 4) { if (parse_uri(uri.s, uri.len, &puri) < 0) { LOG(L_ERR, "is_user_in(): Error while parsing URI\n"); return -5; } VAL_STR(vals) = puri.user; VAL_STR(vals + 2) = puri.host; } else { VAL_STR(vals) = c->digest.username.user; VAL_STR(vals + 2) = *(GET_REALM(&c->digest)); } VAL_TYPE(vals) = VAL_TYPE(vals + 1) = VAL_TYPE(vals + 2) = DB_STR; VAL_NULL(vals) = VAL_NULL(vals + 1) = VAL_NULL(vals + 2) = 0; VAL_STR(vals + 1) = *((str*)_grp); if (group_dbf.use_table(db_handle, table.s) < 0) { LOG(L_ERR, "is_user_in(): Error in use_table\n"); return -5; } if (group_dbf.query(db_handle, keys, 0, vals, col, (use_domain) ? (3): (2), 1, 0, &res) < 0) { LOG(L_ERR, "is_user_in(): Error while querying database\n"); return -5; } if (RES_ROW_N(res) == 0) { DBG("is_user_in(): User is not in group '%.*s'\n", ((str*)_grp)->len, ZSW(((str*)_grp)->s)); group_dbf.free_result(db_handle, res); return -6; } else { DBG("is_user_in(): User is in group '%.*s'\n", ((str*)_grp)->len, ZSW(((str*)_grp)->s)); group_dbf.free_result(db_handle, res); return 1; } }
/* it checks if a user is member of a group */ int diameter_is_user_in(struct sip_msg* _m, char* _hf, char* _group) { str *grp, user_name, user, domain, uri; dig_cred_t* cred = 0; int hf_type; struct hdr_field* h; struct sip_uri puri; AAAMessage *req; AAA_AVP *avp; int ret; unsigned int tmp; grp = (str*)_group; /* via fixup */ hf_type = (int)(long)_hf; uri.s = 0; uri.len = 0; /* extract the uri according with the _hf parameter */ switch(hf_type) { case 1: /* Request-URI */ uri = *(GET_RURI(_m)); break; case 2: /* To */ if (get_to_uri(_m, &uri) < 0) { LM_ERR("failed to extract To\n"); return -2; } break; case 3: /* From */ if (get_from_uri(_m, &uri) < 0) { LM_ERR("failed to extract From URI\n"); return -3; } break; case 4: /* Credentials */ get_authorized_cred(_m->authorization, &h); if (!h) { get_authorized_cred(_m->proxy_auth, &h); if (!h) { LM_ERR("no authorized credentials found " "(error in scripts)\n"); return -4; } } cred = &((auth_body_t*)(h->parsed))->digest; break; } if (hf_type != 4) { if (parse_uri(uri.s, uri.len, &puri) < 0) { LM_ERR("failed to parse URI\n"); return -5; } user = puri.user; domain = puri.host; } else { user = cred->username.user; domain = cred->realm; } /* user@domain mode */ if (use_domain) { user_name.s = 0; user_name.len = user.len + domain.len; if(user_name.len>0) { user_name.len++; user_name.s = (char*)pkg_malloc(user_name.len); if (!user_name.s) { LM_ERR("no pkg memory left\n"); return -6; } memcpy(user_name.s, user.s, user.len); if(user.len>0) { user_name.s[user.len] = '@'; memcpy(user_name.s + user.len + 1, domain.s, domain.len); } else memcpy(user_name.s, domain.s, domain.len); } } else user_name = user; if ( (req=AAAInMessage(AA_REQUEST, AAA_APP_NASREQ))==NULL) { LM_ERR("can't create new AAA message!\n"); return -1; } /* Username AVP */ if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, user_name.s, user_name.len, AVP_DUPLICATE_DATA)) == 0) { LM_ERR("no more pkg memory!\n"); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); goto error1; } /* Usergroup AVP */ if( (avp=AAACreateAVP(AVP_User_Group, 0, 0, grp->s, grp->len, AVP_DUPLICATE_DATA)) == 0) { LM_ERR("no more pkg memory!\n"); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); goto error1; } /* SIP_MSGID AVP */ LM_DBG("******* m_id=%d\n", _m->id); tmp = _m->id; if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&tmp), sizeof(tmp), AVP_DUPLICATE_DATA)) == 0) { LM_ERR("no more pkg memory!\n"); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); goto error1; } /* ServiceType AVP */ if( (avp=AAACreateAVP(AVP_Service_Type, 0, 0, SIP_GROUP_CHECK, SERVICE_LEN, AVP_DUPLICATE_DATA)) == 0) { LM_ERR("no more pkg memory!\n"); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); goto error1; } /* Destination-Realm AVP */ uri = *(GET_RURI(_m)); parse_uri(uri.s, uri.len, &puri); if( (avp=AAACreateAVP(AVP_Destination_Realm, 0, 0, puri.host.s, puri.host.len, AVP_DUPLICATE_DATA)) == 0) { LM_ERR("no more pkg memory!\n"); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LM_ERR("avp not added \n"); goto error1; } #ifdef DEBUG AAAPrintMessage(req); #endif /* build a AAA message buffer */ if(AAABuildMsgBuffer(req) != AAA_ERR_SUCCESS) { LM_ERR("message buffer not created\n"); goto error; } if(sockfd==AAA_NO_CONNECTION) { sockfd = init_mytcp(diameter_client_host, diameter_client_port); if(sockfd==AAA_NO_CONNECTION) { LM_ERR("failed to reconnect to Diameter client\n"); goto error; } } ret =tcp_send_recv(sockfd, req->buf.s, req->buf.len, rb, _m->id); if(ret == AAA_CONN_CLOSED) { LM_NOTICE("connection to Diameter client closed." "It will be reopened by the next request\n"); close(sockfd); sockfd = AAA_NO_CONNECTION; goto error; } if(ret != AAA_USER_IN_GROUP) { LM_ERR("message sending to the DIAMETER backend authorization server" "failed or user is not in group\n"); goto error; } AAAFreeMessage(&req); return 1; error1: AAAFreeAVP(&avp); error: AAAFreeMessage(&req); return -1; }
/* * Check from Radius if a user belongs to a group. User-Name is digest * username or digest username@realm, SIP-Group is group, and Service-Type * is Group-Check. SIP-Group is SER specific attribute and Group-Check is * SER specific service type value. */ int radius_is_user_in(struct sip_msg* _m, char* _hf, char* _group) { str *grp, user_name, user, domain, uri; dig_cred_t* cred = 0; int hf_type; UINT4 service; VALUE_PAIR *send, *received; static char msg[4096]; struct hdr_field* h; struct sip_uri puri; grp = (str*)_group; /* via fixup */ send = received = 0; hf_type = (int)(long)_hf; uri.s = 0; uri.len = 0; switch(hf_type) { case 1: /* Request-URI */ if (get_request_uri(_m, &uri) < 0) { LOG(L_ERR, "radius_is_user_in(): Error while extracting Request-URI\n"); return -1; } break; case 2: /* To */ if (get_to_uri(_m, &uri) < 0) { LOG(L_ERR, "radius_is_user_in(): Error while extracting To\n"); return -2; } break; case 3: /* From */ if (get_from_uri(_m, &uri) < 0) { LOG(L_ERR, "radius_is_user_in(): Error while extracting From\n"); return -3; } break; case 4: /* Credentials */ get_authorized_cred(_m->authorization, &h); if (!h) { get_authorized_cred(_m->proxy_auth, &h); if (!h) { LOG(L_ERR, "radius_is_user_in(): No authorized credentials found (error in scripts)\n"); return -4; } } cred = &((auth_body_t*)(h->parsed))->digest; break; } if (hf_type != 4) { if (parse_uri(uri.s, uri.len, &puri) < 0) { LOG(L_ERR, "radius_is_user_in(): Error while parsing URI\n"); return -5; } user = puri.user; domain = puri.host; } else { user = cred->username.user; domain = *GET_REALM(cred); } if (use_domain) { user_name.len = user.len + domain.len + 1; user_name.s = (char*)pkg_malloc(user_name.len); if (!user_name.s) { LOG(L_ERR, "radius_is_user_in(): No memory left\n"); return -6; } memcpy(user_name.s, user.s, user.len); user_name.s[user.len] = '@'; memcpy(user_name.s + user.len + 1, domain.s, domain.len); } else { user_name = user; } if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) { LOG(L_ERR, "radius_is_user_in(): Error adding User-Name attribute\n"); rc_avpair_free(send); if (use_domain) pkg_free(user_name.s); return -7; } if (use_domain) pkg_free(user_name.s); if (!rc_avpair_add(rh, &send, attrs[A_SIP_GROUP].v, grp->s, grp->len, 0)) { LOG(L_ERR, "radius_is_user_in(): Error adding Sip-Group attribute\n"); return -8; } service = vals[V_GROUP_CHECK].v; if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) { LOG(L_ERR, "radius_is_user_in(): Error adding Service-Type attribute\n"); rc_avpair_free(send); return -9; } if (rc_auth(rh, 0, send, &received, msg) == OK_RC) { DBG("radius_is_user_in(): Success\n"); rc_avpair_free(send); rc_avpair_free(received); return 1; } else { DBG("radius_is_user_in(): Failure\n"); rc_avpair_free(send); rc_avpair_free(received); return -11; } }